警报组件不会再次触发

时间:2020-04-06 12:46:15

标签: javascript reactjs react-hooks

我创建了一个Alert组件,以便能够通过Context.Provider从ReactJS应用程序中的所有组件发送警报。消息存储在一个状态中,并且状态函数作为Context.Provider的值传递。

但是,如果我尝试使用它就可以了,但是第二次却没有用。有什么想法吗?

Alert.js

import React, { useEffect, useState } from "react";
import styled from "styled-components";

const StyledDiv = styled.div`
  width: 100%;
  height: 30px;
  font-size: 1.2em;
  text-align: center;
  background: tomato;
`;

const Alert = ({ message }) => {
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    if (message) {
      setVisible(true);
      setTimeout(() => {
        setVisible(false);
      }, 5000);
    }
  },[message]);
  if (visible) {
    return <StyledDiv id="alert">{message}</StyledDiv>;
  } else return null;
};
export default Alert;

App.js

import React, { useState, createContext } from "react";
import Alert from "./components/alert/Alert";
export const AlertContext = createContext();
function App() {
  const [alert, setAlert] = useState();
  return (
    <>
      <Alert message={alert} />
      <AlertContext.Provider value={setAlert}>
       COMPONENTS HERE
      </AlertContext.Provider>
   </>
  );
}
export default App;

4 个答案:

答案 0 :(得分:2)

只需将消息作为参数放入您的useEffect中:

useEffect(() => {
    if (message) {
      setVisible(true);
      setTimeout(() => {
      setVisible(false);
    }, 5000);
   }
}, [ message ]);

这样,它将在每次消息更改时起作用。

答案 1 :(得分:1)

useEffect带有两个参数。第一个是函数,第二个是数组。每当数组中的元素更改时,该函数就会触发。

useEffect(() => {
    if (message) {
      setVisible(true);
      setTimeout(() => {
        setVisible(false);
      }, 5000);
    }
  }, [ messsage ]);

答案 2 :(得分:0)

这可能是因为您没有清除setTimeout而引起的。尝试这样的事情

  useEffect(() => {
    let timer = null;
    if (message) {
      setVisible(true);
      timer = setTimeout(() => {
         setVisible(false);
      }, 5000);
    }

    return () => clearTimeout(timer);
  }, [message]);

答案 3 :(得分:0)

问题在于App.js中的状态未更新,因此我将其作为道具发送给Alert组件以在此进行更新。

Alert.js

import React, { useEffect } from "react";
import styled from "styled-components";

const StyledDiv = styled.div`
  width: 100%;
  height: 30px;
  font-size: 1.2em;
  text-align: center;
  background: tomato;
`;

const Alert = ({ setAlert, message }) => {
  useEffect(() => {
    if (message) {
      let timer = setTimeout(() => {
        setAlert(null);
      }, 5000);
      return () => clearTimeout(timer);
    }
  }, [message]);
  if (message) {
    return <StyledDiv id="alert">{message}</StyledDiv>;
  } else return null;
};
export default Alert;

App.js

import React, { useState, createContext } from "react";
import Alert from "./components/alert/Alert";
export const AlertContext = createContext();
function App() {
  const [alert, setAlert] = useState();
  return (
    <>
      <Alert setAlert={setAlert} message={alert} />
      <AlertContext.Provider value={setAlert}>
       COMPONENTS HERE
      </AlertContext.Provider>
   </>
  );
}
export default App;

每个人都提供了帮助。非常感谢,您的宝贵意见。