skip to Main Content

If I have two select controls, one which is dependant on the other, so that if I change selectA value, selectB value will be selected depending on it:

...
const [values, setValues] = useState({ selectA: undefined, selectB: undefined });
const setSelectValue = (field, value) => {
  setValues((current) => {...current, [field]: value});
}

return (
  <>
    <Select
      name="selectA"
      value={values.selectA}
      onChange={(val) => setSelectValue('selectA', val)}
      ...
    />
    <Select
      name="selectB"
      value={values.selectB}
      onChange={(val) => setSelectValue('selectB', val)}
      ...
    />
  </>
);

In terms of performance, would it be best to use useEffect or just change the selectB value on the selectA onChange method?

// Is it best to use useEffect
useEffect(() => {
  setSelectValue('selectB', values.selectA.potato);
}, [values.selectA]);

// ... or is it best to change it directly on onChange method?
<Select
  name="selectA"
  value={values.selectA}
  onChange={(val) => {
    setSelectValue('selectA', val);
    setSelectValue('selectB', val.potato);
  }}
  ...
/>

Does it matter at all? Is there any difference in terms of performance between both?

I understand that useEffect can come handy for side effects that depend on data that can be updated at any time, but in this case I know the data right when I select it on selectA and it cannot be changed any other way, so I wonder if it’s necessary to make a useEffect to observe that value rather than just grabbing it and setting it directly.

Keep in mind that the value of selectA.potato can be of any type, but I’m thinking of it being an object.

2

Answers


  1. About the performance, setting the value directly in onChange is better. With useEffect you do twice rerenders, since the second update will occur after the first rerender. But in most cases that won’t matter that much.

    useEffect is good if your selectA getting updated from more than 1 place. For example if you have CRUD operations on it, the update logic for selectB will be in 1 place, not on each operation.

    In some cases you will be forced to update the second state in the onChange, if you want the UI to rerender with the both new values instead of 1 by 1

    Login or Signup to reply.
  2. Yes useEffect might be slower but I don’t think performance is the main concern here.

    In general the official advice is not to overuse useEffect. If you can do something without it, it is better probably to do it without it.

    From the docs:

    Effects are an escape hatch from the React paradigm. They let you
    “step outside” of React and synchronize your components with some
    external system like a non-React widget, network, or the browser DOM.
    If there is no external system involved (for example, if you want to
    update a component’s state when some props or state change), you
    shouldn’t need an Effect. Removing unnecessary Effects will make your
    code easier to follow, faster to run, and less error-prone.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search