简体   繁体   English

使用 useEffect 钩子避免无限循环

[英]Avoid infinite loop with useEffect hook

I am trying to display an updated list of items every time a new item is added using the form.每次使用表单添加新项目时,我都试图显示更新的项目列表。 Using the useEffect hook I keep getting stuck in an infinite loop that crashes the page.使用 useEffect 钩子,我不断陷入使页面崩溃的无限循环中。 I am not sure how to add some sort of validation that ask to re-render my component only if a new item has been added.我不确定如何添加某种验证,仅在添加新项目时才要求重新渲染我的组件。

@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;

NOTE: I would like to renders updating data without reloading the page every time a new item has been added.注意:每次添加新项目时,我想呈现更新数据而无需重新加载页面。 I am trying to achieve the same result as this demo: https://taniarascia.github.io/react-hooks/ Is there a Hooks only approach to this?我试图实现与此演示相同的结果: https : //taniarascia.github.io/react-hooks/是否有仅使用 Hooks 的方法?

Inside the “useEffect”, it will update the state “currentAsset”.在“useEffect”内部,它将更新状态“currentAsset”。 Then it will trigger the component to re-render again.然后它会触发组件再次重​​新渲染。 As a result, “useEffect()” will run again and update the state.结果,“useEffect()”将再次运行并更新状态。 Next, the whole process repeats again, and you're trapped inside an infinite loop.接下来,整个过程再次重复,你被困在一个无限循环中。

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

You can't update state variable that in the dependancies for useEffect inside it you can make multiple useEffects you should retrieve it first in empty useEffect then make another one to listen on currentAsset change您不能更新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]);

Usually, queries make items change, we should listen changes of query, and update items.通常,查询会使项目发生变化,我们应该监听查询的变化,并更新项目。 just add a query state to make logic clear.只需添加一个查询状态即可使逻辑清晰。


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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM