【问题标题】:useEffect doesn't track changes when new item in my database is created在我的数据库中创建新项目时,useEffect 不会跟踪更改
【发布时间】:2021-05-18 18:06:16
【问题描述】:

我在 useEffect() 中获取所有用户的事务,但是当我创建一个新事务时,useEffect 不会重新加载,那么我需要刷新页面才能看到更改。我已经进行了很多搜索,并且尝试了诸如 useCallback() 和 useRef() 和 useEffect() 之类的方法,但仍然无法正常工作,可能是因为我不太了解如何正确使用它们。当我传递我想要观看的数据时,在我的情况下 [transactions] 我得到一个无限循环,因为 setState 会混淆我的状态,然后组件将重新加载,因此 useEffect 将调用我的函数并且 setState 将被触发,这将发生重新来过。

const [transactions, setTransactions] = useState([]);

useEffect(() => {
    getUserTransactions();
  }, []);

  const getUserTransactions = async () => {
    if (currentUser) {
      const token = await firebase.auth().currentUser.getIdToken();
      axios
        .get("http://localhost:8080/transactions", {
          headers: {
            "Content-Type": "application/json",
            Authorization: token,
          },
        })
        .then((res) => {
          setTransactions(res.data);
        })
        .catch((err) => console.log(err));
    }
  };

我想知道异步操作是否会导致这个问题,因为在另一个项目中,我没有遇到任何问题。

const createTransaction = async (e) => {
    e.preventDefault();

    if (currentUser) {
      const token = await firebase.auth().currentUser.getIdToken();
      const data = {
        title: textRef.current.value,
        price: priceRef.current.value,
        category: categoryRef.current.value,
      };
      axios
        .post("http://localhost:8080/transactions", data, {
          headers: {
            "Content-Type": "application/json",
            Authorization: token,
          },
        })
        .then((res) => {
          setTransactions(prevTransactions => [...prevTransactions, res.data.rows])
        })
        .catch((err) => console.log(err));

      setIsOpen(false);
    }
  };

【问题讨论】:

    标签: react-hooks use-effect


    【解决方案1】:

    那是因为你的 useEffect 的依赖数组是空的,这意味着它只发生一次,在页面的初始呈现时。

    useEffect 的目的是对状态变化做出反应,它不知道您的后端。因此,在添加新交易时,您应该相应地更改状态。我会建议一些类似的东西:

    当您添加事务时,服务器的响应将包含您需要在前端显示它的所有详细信息,因此当您获取响应对象时,只需通过附加它来更改状态。比如:

    const addTransaction = async () => {
        const newTransactionData = (await axios.post('http://localhost:8000/transactions/add' /*or whatever your request looks like*/)).data
        setTransactions(prevTransactions => [...prevTransactions, newTransactionData])
    }
    

    【讨论】:

    • 我已经尝试过您的建议,但得到了相同的结果。我仍然需要刷新页面才能看到更改。但是感谢您的尝试
    • 另一种解决方案是每次添加事务时调用getUserTransactions
    • 它也可以,但是可以这样做吗?我的意思是,这是一个好习惯吗?至少我不需要每秒钟都调用我的发球。
    • 没关系。不理想,我第一次建议的是我认为最好的解决方案,我强烈建议您调试它并找出它为什么不起作用。如果您有很多事务,它可能会变慢,但您始终可以使用分页。
    猜你喜欢
    • 2021-07-11
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    相关资源
    最近更新 更多