1

I have a use effect which is supposed to keep a button disabled until a row on a table has been clicked, then the button will be clickable. For some reason, it is not updating the state. I put a console log in the 'if' part of my use effect to check it was even getting to that bit and the console log prints out fine so I am not sure as to why the button will not change.

const [disabledSubmitFormButton, setDisabledSubmitFormButton] = useState(false)

const [selectedOptions, setSelectedOptions] = useState([{
        name: '',
        age: '',
        city: '',
    }])


useEffect(() => {
        if (selectedOptions.length > 0) {
            setDisabledSubmitFormButton(false)
            console.log("hiiii")
        } else {
            setDisabledSubmitFormButton(true)
        }
    }, [selectedOptions])

And the button is listening out for the submitFormButton state like so -

<Button disabled={submitFormButton}>Submit</Button>

I have a table with rows in it, when the user select a row in the table, this is when the button should turn clickable and not be disabled. When the user clicks off the table, the button should be disabled again.

<DataTable value={optionsContext.list} header={header} sortField="id" sortOrder={-1} globalFilter={globalFilter} selectionMode="multiple"
                    selection={selectedOptions} onSelectionChange={e => setSelectedOptions(e.value)}>
                    <Column className="table-column" field="name" header="Name" sortable filter filterPlaceholder="Search by Name" />
                    
etc. 

monkeys73
  • 171
  • 1
  • 3
  • 13
  • Why do you use useEffect for this ?, when you change selectedOptions obj in your local state you dont need any lifecycle, just put this operations in a normal function and use only useState hook. – Süleyman GÜNDÜZ Jun 26 '20 at 08:05
  • 1
    So, the button starts out enabled because `submitFormButton` is false? And then the effect runs on mount and checks the `selectedOptions` array length and see it is length === 1 and sets `submitFormButton` true which will disable the button? Is this reading correct? – Drew Reese Jun 26 '20 at 08:06
  • the code in general should be working imho, I suspect you are not updating the `selectedOptions` state correctly. However, IIUC your `useEffect` does the opposite of what you want: it will disable the button when the `selectedOptions` array is not empty. – hotpink Jun 26 '20 at 08:20
  • @DrewReese I have updated my question now, hopefully this makes more sense. Apologies as I had made a mistake – monkeys73 Jun 26 '20 at 09:19

2 Answers2

1

Note, that you have selectedOptions in the dependency array of your useEffect. It means that it will run once upon component init and will never run again until the selectedOptions change. That is why you can see console log for one time.

useEffect(() => {
        if (selectedOptions.length > 0) {
            setSubmitFormButton(true)
            console.log("hiiii")
        } else {
            setSubmitFormButton(false)
        }
    }, [selectedOptions]) // <-- here it is

So I assume that when user clicks on the options you actually do not change them, or change and item inside of selectedOptions array but the reference to the array is still the same, so React doesn't consider it as a change. In order to trigger react properly in this case you need to update selectedOptions state with a new array.

For example your handleClick function can look like this:

handleClick() {
   setSelectedOptions([...selectedOptions]) // <-- new array is passed 
}

Note, that in the example above I just replace array with a new one with the same content. In real app you will probably need to update items inside, so you can use .map() method, or any other approach which will return new array with updated items inside.

Artem Arkhipov
  • 7,025
  • 5
  • 30
  • 52
0

Just create a func like this and pass it somewhere where you want yo call it.

const aFunction = () => {
  ..
  ..
  .. // make the changes

  setSubmitFormButton(false or true);
}