Simplify multiple instances of useState

Viewed 396

In my ReactJS code, I need to store multiple variables as separate states like this. Is there any easier way to create them? Because now I use useState function repeatedly.

  const [dutyCode, setDutyCode] = useState("");
  const [startTime, handleStartTime] = useState(new Date());
  const [endTime, handleEndTime] = useState(new Date());
  const [activityType, setActivityType] = useState("");
  const [dutyType, setDutyType] = useState("");
3 Answers

You can just use one state object and destructure it:

const [state, setState] = useState({
    dutyCode: "",
    startTime: new Date(),
    endTime: new Date(),
    activityType: "",
    dutyType: "",
});

const {
    dutyCode,
    startTime,
    endTime,
    activityType,
    dutyType,
} = state;

const updateState = (update) => setState({ ...state, ...update });

Easier ways:

  1. useReducer as docs states:

useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one.

  1. Manage a single state:
const INITIAL = {
  startTime: "",
  endTime: new Date(),
  dutyCode: "",
  dutyType: new Date(),
};

// Some multi-keyed state
const [state, setState] = useState(INITIAL);

// Example for handling sub-value
const handleDutyCode = (dutyCode) =>
  useState((prev) => ({ ...prev, dutyCode }));

Since you do not have any complex logic to update state, a better approach for you would be to use an object to store multiple states. To simplify your solution, you can write a custom hook that merges the state before updating, so that you don't have to worry about it whenever you are updating state

const useMergedState = (initialVal) => {
   const [value, setValue] = useState(initialVal);
   const setMergedValue = useCallback((updatedValue) => {
       setValue(prev => ({
          ...prev,
          ...updatedValue,
       }))
   }, []);
   return [value, setMergedValue] ;
}

and use it like

const [state, setState] = useMergedState({
  startTime: "",
  endTime: new Date(),
  dutyCode: "",
  dutyType: new Date(),
});

and update like

setState({startTime: new Date()});
Related