reactjs 如何使用React钩子显示多条消息?[duplicate]

wrrgggsh  于 2023-02-03  发布在  React
关注(0)|答案(2)|浏览(131)
    • 此问题在此处已有答案**:

(9个答案)
5小时前关门了。
我尝试使用提供程序和钩子显示多条消息。但是我不能显示多条消息。一条消息一次显示一条消息,不知道为什么?
下面是我代码https://codesandbox.io/s/new-mountain-cnkye5?file=/src/App.tsx:274-562

React.useEffect(() => {
    setTimeout(() => {
      utilContext.addMessage("error 2 sec");
    }, 300);

    setTimeout(() => {
      utilContext.addMessage("error 5 mili sec");
    }, 2000);

    setTimeout(() => {
      utilContext.addMessage("error 1  sec");
    }, 1000);
  }, []);

我还使用Map功能来呈现所有的消息。

return (
    <>
      {messages.map((msg, index) => (
        <div key={`Toast-Message-${index}`}>
          {msg.msg}
          <button
            onClick={(event) => {
              alert("000");
            }}
          >
            close
          </button>
        </div>
      ))}

      <ConfirmationDialogContext.Provider value={value}>
        {children}
      </ConfirmationDialogContext.Provider>
    </>
  );
    • 预期产出**:一段时间后它将显示3条消息。
ygya80vv

ygya80vv1#

更改您的

const addMessage = (message: string, status: "success" | "error") => {
    setmessages([...messages, { msg: message, type: status, duration: 5000 }]);
  };

const addMessage = (message: string, status: "success" | "error") => {
    setmessages((currentMessages) => [
      ...currentMessages,
      { msg: message, type: status, duration: 5000 }
    ]);
  };

这是因为您同时调用了3个addMessage,因此messages变量在所有三个调用中都具有相同的值。
有关此语法的详细信息,请参阅基于先前状态更新状态

t9aqgxwy

t9aqgxwy2#

每次添加消息时,上下文都会发生变化,而在useEffect依赖项中,上下文并不作为dep,这意味着您只向第一个上下文示例添加消息,而始终呈现最新的上下文示例。
但是,如果您将上下文添加到useEffect依赖项中,则会出现无限循环。
一个(不好)的解决方案是使用useRef跟踪每个setTimeout,如下所示:

export default function App() {
  const utilContext = useConfirmationDialog();
  const m1Ref = React.useRef(false);
  const m2Ref = React.useRef(false);
  const m3Ref = React.useRef(false);

  React.useEffect(() => {
    console.log("useEffect");
    const s = [];
    if (m1Ref.current === false) {
      const s1 = setTimeout(() => {
        utilContext.addMessage("error 300 msec");
      }, 300);
      s.push(s1);
      m1Ref.current = true;
    }
    
    if (m2Ref.current === false) {
      const s2 = setTimeout(() => {
        m2Ref.current = true;
        utilContext.addMessage("error 2 sec");
      }, 2000);
      s.push(s2);
    }
    
    if (m3Ref.current === false) {
      const s3 = setTimeout(() => {
        m3Ref.current = true;
        utilContext.addMessage("error 1  sec");
      }, 1000);
      s.push(s3);
    }

    return () => {
      s.forEach((x) => clearTimeout(x));
    };
  }, [utilContext]);
  
  return (
    <Typography>
      MUI example. Please put the code to reproduce the issue in src/App.tsx
    </Typography>
  );
}

我认为,您应该将信息呈现的延迟从发送者转移到上下文中,如下所示:

const addMessage = (delay: number, message: string, status: "success" | "error") => {
    setTimeout(() => {
      setmessages((currentMessages) => [
        ...currentMessages,
        { msg: message, type: status, duration: 5000 }
      ]);
    }, delay);
  };

相关问题