0

I have a React component:

const ProjectFamiliesFilterInput = React.memo(({ familyOptions, analysisGroupOptions, projectAnalysisGroupsByGuid, value, onChange, ...props }) => {
  const allFamiliesSelected = !value.familyGuids || value.familyGuids.length === familyOptions.length

...
...

return (
    <Form.Group inline widths="equal">
      <BooleanCheckbox
        {...props}
        value={allFamiliesSelected}
        onChange={selectAllFamilies}
        width={5}
        label="Include All Families"
      />
    </Form.Group>
)
})

I want allFamiliesSelected to be set upon first mount depending on whether value.familyGuids.length > 0. How to achieve that with react hooks?

Clarification:

allFamiliesSelected = value.familyGuids.length === 0 - needs to be done on the first mount, but allFamiliesSelected = !value.familyGuids || value.familyGuids.length === familyOptions.length - on subsequent updates and not on the first mount.

Nikita Vlasenko
  • 4,004
  • 7
  • 47
  • 87

3 Answers3

0

To initialize a hook on render you need pass the value when initializing the hook with useState

const [allFamiliesSelected, updateAllFamiliesSelected ] = useState(!value.familyGuids || value.familyGuids.length === familyOptions.length)
Shmili Breuer
  • 3,927
  • 2
  • 17
  • 26
  • No, what I need is that `!value.familyGuids || value.familyGuids.length === familyOptions.length` to be updated on each update, but `value.familyGuids.length > 0` to be updated only on mounting the component. `!value.familyGuids` is not the same thing as `value.familyGuids.length === 0` – Nikita Vlasenko Sep 03 '20 at 21:27
  • Most probably I need to prevent `!value.familyGuids || value.familyGuids.length === familyOptions.length` on the first mount since it will override `value.familyGuids.length === 0` condition – Nikita Vlasenko Sep 03 '20 at 21:32
0

I think I was able to fix this issue using the following code:

const [ allFamiliesSelected, updateAllFamiliesSelected ] = useState(value.familyGuids.length === 0)
           
  const firstUpdate = useRef(true)
  useLayoutEffect(() => {
    if (firstUpdate.current) {
      firstUpdate.current = false;
      return;
    }      
    console.log(value)
    updateAllFamiliesSelected(!value.familyGuids || value.familyGuids.length === familyOptions.length)
  })

The following thread provided me with almost complete solution: Make React useEffect hook not run on initial render

I got another issue though that I posted as a separate thread: Redux-form: update syncErrors cause form to skip modifications

Nikita Vlasenko
  • 4,004
  • 7
  • 47
  • 87
-1

You have to use useState();

function ExampleWithManyStates() {
  // Declara várias variáveis de state!
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
  // ...
}

https://pt-br.reactjs.org/docs/hooks-overview.html