【问题标题】:Avoid infinite loop with useEffect hook使用 useEffect 钩子避免无限循环
【发布时间】:2021-03-07 21:05:17
【问题描述】:

每次使用表单添加新项目时,我都会尝试显示更新的项目列表。使用 useEffect 钩子,我一直卡在一个导致页面崩溃的无限循环中。 我不确定如何添加某种验证,仅在添加新项目时才要求重新渲染我的组件。

@app.route('/assets')
def get_assets():
  print('this is a test')
  cursor = assets.find() 
  list_cur = list(cursor)
  assets = dumps(list_cur)
  return assets

 function Assets() {
  const [currentAsset, setCurrentAsset] = useState(0);

  useEffect(() => {
    (async () => {
      const result = await fetch('/assets')
      const data = await result.json()
      setCurrentAsset(data)
    })()
  }, [currentAsset]);
 
 
  return (
    <div>
      <header>
      <table className="table table-striped">
        <thead>
          <tr>
            <th>Ip Address</th>
            <th>Asset Type</th>
            <th>Username</th>
            <th>Notes</th>
          </tr>
        </thead>
        <tbody>
        {Object.values(currentAsset).map((item, index) => (
          <tr key={item._id? item._id.$oid: null}>
            <td>{item.ip_address}</td>
            <td>{item.asset_type}</td>
            <td>{item.username}</td>
            <td>{item.notes}</td>
          </tr>
          )
        )}
        </tbody>
      </table>
      </header>
    </div>
  );

}

export default Assets;

注意:每次添加新项目时,我都希望在不重新加载页面的情况下呈现更新数据。我试图达到与此演示相同的结果:https://taniarascia.github.io/react-hooks/ 是否有唯一的 Hooks 方法?

【问题讨论】:

  • 这没有意义,你不要在前端添加资产,你从后端获取它们。前端如何知道新资产何时可用?
  • 什么意思?我正在尝试查看更新的列表而无需刷新浏览器。试图达到与此相同的结果:taniarascia.github.io/react-hooks

标签: reactjs react-hooks use-effect


【解决方案1】:

在“useEffect”内部,它会更新状态“currentAsset”。然后它会触发组件再次重​​新渲染。 结果,“useEffect()”将再次运行并更新状态。接下来,整个过程再次重复,你被困在一个无限循环中。

 useEffect(() => {
    (async () => {
      const result = await fetch('/assets')
      const data = await result.json()
      setCurrentAsset(data)
    })()
  }, []);

【讨论】:

  • 这只会获取一次结果,我需要重新加载页面才能看到更新的列表
  • 如果你想在时间基准上获取数据,或者如果你想在 prop 更改时获取数据,请使用 setInterval,然后将 prop 传递到 useEffect 的空数组中[
【解决方案2】:

你不能更新 state variable 里面的 useEffect 的依赖 你可以制作多个useEffects 您应该先在空的useEffect 中检索它,然后再制作另一个以在currentAsset 更改时收听

useEffect(() => {
    /// this will work as componentDidMount 
   // will be called only once at the first after rendering the component
    (async () => {
     const result = await fetch('/assets')
     const data = await result.json()
     setCurrentAsset(data)
   })()
 }, []);

 useEffect(() => {
    // listen on the change of the currentAsset here but DONOT update it here
 }, [currentAsset]);

【讨论】:

  • 这不会更新列表,直到我重新加载页面。
  • 是的,你应该指定列表应该何时更新或取决于哪个 var 但你不应该依赖于你在 useeffect 中更新的那个
【解决方案3】:

通常,查询会使项目发生变化,我们应该监听查询的变化,并更新项目。只需添加一个查询状态以使逻辑清晰。


function Assets() {
  const [currentAsset, setCurrentAsset] = useState({});
  const [query, setQuery] = useState('');

  useEffect(() => {
    (async () => {
      const result = await fetch('/assets?query=' + query)
      const data = await result.json()
      setCurrentAsset(data)
    })()
  }, [query]);
 
  return (
    <div>
      <header>
      <table className="table table-striped">
        <thead>
          <tr>
            <th>Ip Address</th>
            <th>Asset Type</th>
            <th>Username</th>
            <th>Notes</th>
          </tr>
        </thead>
        <tbody>
        {Object.values(currentAsset).map((item, index) => (
          <tr key={item._id? item._id.$oid: null}>
            <td>{item.ip_address}</td>
            <td>{item.asset_type}</td>
            <td>{item.username}</td>
            <td>{item.notes}</td>
          </tr>
          )
        )}
        </tbody>
      </table>
      </header>
    </div>
  );

}

export default Assets;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 2021-04-10
    • 1970-01-01
    • 2021-12-04
    • 2021-12-09
    • 2020-10-27
    • 1970-01-01
    相关资源
    最近更新 更多