ReactJS:第一个 useEffect 在第二个被触发之前不会更新状态

我有一个聊天组件,它使用 API 填充messages状态,还有不同的区域有不同的聊天,我将它们作为道具传递给组件。


在这个组件中,我有 3 个useEffects,但我对其中两个不能正常工作的组件感兴趣。在第一个 useEffect 中,我有一些代码基本上将messages区域更改时的状态重置为undefined. 我需要这样做才能区分在我显示加载组件<Spinner />的地方尚未调用 API 还是已调用 API 并且它已检索空数组以显示<NoData>组件。


我遇到的问题是,当我更改区域时,useEffects会按应有的方式触发,但第一个useEffect不会在调用messages第二个之前将状态更新为未定义useEffect。由于历史推送而重新渲染后,消息未定义,但第二个useEffect不再被触发。我不明白为什么状态没有在useEffect第二个之前的第一个更新。同样奇怪的是,这曾经对我有用,现在却没有。我在没有推送到 git 的情况下更改了一些东西,现在我很困惑。下面的代码:


export default function ChatPage({ history, match, area, ...props }) {

  const [templates, setTemplates] = useState([]);

  const [advisors, setAdvisors] = useState([]);

  const [messages, setMessages] = useState(undefined);

  const [conversation, setConversation] = useState([]);

  const [chatToLoad, setChatToLoad] = useState(false);

  const [isOpen, setIsOpen] = useState(false);

  const [linkOrigin, setLinkOrigin] = useState("");

  const [headerText, setHeaderText] = useState("");


  // useEffect used to reset messages and conversation state

  // triggered on area change(messages and conversation reset)

  // and customer ID change(conversation reset).

  // Required to distinguish between API call not being made yet

  // and API returning no data.

  useEffect(() => {

    if (match.params.id) {

      setLinkOrigin(match.params.id);

    }


    if (messages) {

      if (match.params.id && messages.length !== 0) {

        let matches = messages.filter(

          (message) => message.ORIGINATOR === match.params.id

        );


        if (matches.length !== 0 && match.params.id === linkOrigin) {

          setMessages(undefined);

          history.push("/chats/" + match.params.area);

        }

      }

    }


    setConversation([]);

  }, [area, match.params.id]);


  // API calls

  useEffect(() => {

    if (templates.length === 0) {

      api.getTemplates().then((templates) => {

        setTemplates(templates);

      });

    }


    if (advisors.length === 0) {

      api.getAgents().then((advisors) => {

        setAdvisors(advisors);

      });

    }


陪伴而非守候
浏览 350回答 1
1回答

蛊毒传说

你不能通过这种方式得到你想要的。在 useEffect 中应用的状态更改在下一个渲染周期之前不会生效,以下回调仍将看到当前的 const 值。如果您想更改当前渲染周期中的值,您唯一的选择是将您的 const 放宽为 let 并自己设置变量。毕竟:你期待一个 const 改变,不是吗?;)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript