簡體   English   中英

state 更改后 React useEffect 未運行

[英]React useEffect not running after state change

我正在查詢 Firebase 實時數據庫,將結果保存到 state 然后渲染結果。

我的數據沒有顯示,因為頁面在獲得數據之前正在呈現。 我不明白的是為什么

useEffect(() => {
    for (var key in projects) {
      var projectData = {
        title: projects[key].title,
        description: projects[key].description,
      };
      result.push(<Project props={projectData} />);
    }
   }, [projects]); 

一旦項目 state 更改被觸發,填充數組並觸發條件渲染行,我的使用效果就不會運行。

我在這里錯過了什么?

  const [projects, setProjects] = useState();
  const { user } = useUserAuth();
  const result = [];
  const dbRef = ref(db, `/${user.uid}/projects/`);

  useEffect(() => {
    onValue(dbRef, (snapshot) => {
      setProjects(snapshot.val());
    });
  }, []);

  useEffect(() => {
    for (var key in projects) {
      var projectData = {
        title: projects[key].title,
        description: projects[key].description,
      };
      result.push(<Project props={projectData} />);
    }
  }, [projects]);

  return (
    <>
      {result.length > 0 && result}
    </>
  );
};

result也應該是一個狀態!

現在每個重新渲染result都被設置為[] 因此,當 useEffect 確實啟動時,隨后的重新渲染將再次將result設置為[]

這不應該是useEffect 效果渲染后運行,但您試圖將<Project>元素放在頁面上,這必須渲染期間發生。 只需在組件主體中執行即可:

  const [projects, setProjects] = useState();
  const { user } = useUserAuth();
  const dbRef = ref(db, `/${user.uid}/projects/`);

  useEffect(() => {
    onValue(dbRef, (snapshot) => {
      setProjects(snapshot.val());
    });
  }, []);

  const result = [];
  for (var key in projects) {
    var projectData = {
      title: projects[key].title,
      description: projects[key].description,
    };
    result.push(<Project props={projectData} />);
  }

  return (
    <>
      {result.length > 0 && result}
    </>
  );

result.push不會就地改變result 相反,它會使用新值創建數組的副本。

作為解決方案,您可以通過將result提升到 state 變量中來使當前代碼正常工作,如下所示:

const [result, setResult] useState([])
...
 useEffect(() => {
    for (var key in projects) {
      ...
      setResult([...result, <Project props={projectData} />])
    }
  }, [result, projects]);

然而,這個解決方案會導致無限循環......

我的建議是重做一些邏輯並使用projects來渲染您的Project組件,而不是創建一個變量來封裝您的渲染組件。 像這樣:

  const [projects, setProjects] = useState();
  const { user } = useUserAuth();
  const dbRef = ref(db, `/${user.uid}/projects/`);

  useEffect(() => {
    onValue(dbRef, (snapshot) => {
      setProjects(snapshot.val());
    });
  }, []);

  return (
    <>
      {projects.length > 0 && projects.map(project=>{
        var projectData = {
          title: projects[key].title,
          description: projects[key].description,
        };
        return <Project props={projectData} />
       })}
    </>
  );
};

你的組件沒有重新渲染,因為反應不關心你的result變量被填充。

像這樣將其設置為 state: const [result, setResult] = useState([]);

然后使用 map 返回數組的每一項作為 desire 組件:

{result.length > 0 && result.map((data, index) => <Project key={index} props={data} />)}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM