更改React状态会在稍后重新渲染,然后应该

时间:2020-08-21 20:02:38

标签: javascript reactjs use-state react-state react-state-management

我有一个功能组件,用于管理多个状态,其中包括一个状态,该状态用于存储索引,单击适当的按钮时将使用该索引呈现一种表类型。该按钮的OnClick调用回调函数,该函数运行一个单击处理程序。单击处理程序将索引状态更改为与数组条目相同的“索引”,在该数组中,我存储了一个对象,该对象包含用于呈现子组件的信息。

我希望onClick的状态在渲染发生之前会改变,因此组件可以正确渲染。但是它只会在稍后进行渲染。

我已经尝试在索引状态更改时调用useEffect-hook重新呈现,但这都没有帮助。

以下是该代码的简化版本:

export const someComponent = () => {
  [index, setIndex] = useState(-1);
   
  const handleClick = (id) => {
    setIndex(id);
  
    // This is a function, I use to render the table
    buildNewComponent(index);
  }
}

在代码中进一步“下移”,我得到了一个函数,该函数正在呈现表条目。在那里,我在表的子组件中传递了onClick道具,如下所示:

<SomeEntryComponent
  onClick={() => handleClick(arrayEntry.id)}
>
// some code which is not affecting my problem
</SomeEntryComponent>

因此告诉我们:当onClick触发时,它会在第二次按下该组件时首先呈现该组件,因为首先状态会发生变化。

任何人都可以告诉我为什么会发生这种情况以及如何使其正常工作吗?

3 个答案:

答案 0 :(得分:1)

调用"gradle project sync failed"gradle尚未更新。您只是调用setState,不能保证此后立即更新该值。您可以在此处使用buildNewComponent或在以index为依存关系的useEffect中调用id

答案 1 :(得分:1)

正如其他人所述,这是一个同步性问题,其中indexbuildComponent被调用之后被更新。

但是从设计的角度来看,最好通过其值来断言index存在,而不是在处理程序中对其进行标记。我不知道buildComponent背后的细节,但是您可以将其转换为组件的条件渲染。

与手动创建相反,您的组件渲染从其数据中获取。

export const someComponent = () => {
    [index, setIndex] = useState(-1);

    const handleClick = (id) => setIndex(id);

    const indexHasBeenSelected = index !== -1
    return (
        <div>
            {indexHasBeenSelected && <NewComponent index={index} />}
        </div>
    )
}

答案 2 :(得分:0)

我相信,如果您使用useEffect并监视index的更改,您将具有正确的行为。

export const someComponent = () => {
  [index, setIndex] = useState(-1);

  useEffect(() => {
    // This is a function, I use to render the table
    buildNewComponent(index);
  }, [buildNewComponent, index])
   
  const handleClick = (id) => {
    setIndex(id);    
  }
}

该过程将是:

  1. 用户点击并致电handleClick时,它将使用新的setIndex派发id
  2. index将更改为相同的id
  3. useEffect将看到index中的更改,并将呼叫buildNewComponent

重要的一件事是用buildNewComponent包装useCallback以避免意外行为。