Is there a generic way to set state in React Hooks? How to manage multiple states?

Yes, with hooks you can manage complex state (without 3rd party library) in three ways, where the main reasoning is managing state ids and their corresponding elements.

  1. Manage a single object with multiple states (notice that an array is an object).
  2. Use useReducer if (1) is too complex.
  3. Use multiple useState for every key-value pair (consider the readability and maintenance of it).

Check out this:

// Ids-values pairs.
const complexStateInitial = {
  input1: "",
  input2: "",
  input3: ""
  // .. more states
};

function reducer(state, action) {
  return { ...state, [action.type]: action.value };
}

export default function App() {
  const [fromUseState, setState] = useState(complexStateInitial);

  // handle generic state from useState
  const onChangeUseState = (e) => {
    const { name, value } = e.target;
    setState((prevState) => ({ ...prevState, [name]: value }));
  };

  const [fromReducer, dispatch] = useReducer(reducer, complexStateInitial);

  // handle generic state from useReducer
  const onChangeUseReducer = (e) => {
    const { name, value } = e.target;
    dispatch({ type: name, value });
  };
 
  return (
    <>
      <h3>useState</h3>
      <div>
        {Object.entries(fromUseState).map(([key, value]) => (
          <input
            key={key}
            name={key}
            value={value}
            onChange={onChangeUseState}
          />
        ))}
        <pre>{JSON.stringify(fromUseState, null, 2)}</pre>
      </div>

      <h3>useReducer</h3>
      <div>
        {Object.entries(fromReducer).map(([key, value]) => (
          <input
            name={key}
            key={key}
            value={value}
            onChange={onChangeUseReducer}
          />
        ))}
        <pre>{JSON.stringify(fromReducer, null, 2)}</pre>
      </div>
    </>
  );
}

Edit Handle Multiple State

Notes

  • Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:
setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

Refer to React Docs.

Leave a Comment