React.js UseFfect不更新UseState

时间:2020-06-26 08:01:21

标签: reactjs typescript react-hooks use-effect use-state

我有一个使用效果,应该使该按钮保持禁用状态,直到单击了表中的一行,然后该按钮才可以单击。由于某种原因,它没有更新状态。我在使用效果的“如果”部分中放入了控制台日志,以检查它是否已达到该位,并且控制台日志可以正常打印,因此我不确定为什么按钮不会更改。

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])

按钮像这样监听侦听SubmitFormButton状态-

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

我有一个带有行的表,当用户在表中选择一行时,这是按钮应变为可单击而不是被禁用的时间。当用户单击表格后,应再次禁用该按钮。

<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. 

2 个答案:

答案 0 :(得分:1)

请注意,您的useEffect的依赖项数组中有selectedOptions。 这意味着它将在组件初始化时运行一次,并且在selectedOptions更改之前永远不会再次运行。这就是为什么您可以一次查看控制台日志的原因。

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

所以我假设当用户单击选项时,您实际上并没有更改它们,也没有更改selectedOptions数组内的项目,但是对该数组的引用仍然相同,因此React不会考虑它作为改变。为了在这种情况下触发正确的反应,您需要使用新的数组更新selectedOptions状态。

例如,您的handleClick函数看起来像这样:

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

请注意,在上面的示例中,我只是将数组替换为内容相同的新数组。在实际的应用程序中,您可能需要更新内部的项目,因此可以使用.map()方法或任何其他方法来返回内部具有更新的项目的新数组。

答案 1 :(得分:0)

只需创建一个这样的函数并将其传递到您要调用它的地方即可。

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

  setSubmitFormButton(false or true);
}