首页 > 解决方案 > 无法使用钩子在我的本地状态中设置响应数据反应

问题描述

我正在使用功能组件并且是初学者。我成功地收到了来自 API 的响应,但是当我将它设置为本地 useState 变量时,它仍然是空的。我无法理解如何解决这个问题。

方法一:

const [sites,setSites]=useState([]);
useEffect(()=>{
    getAllSites().then(res=>{
      console.log("res",res.sites);//response received successfully
      setSites(res.sites);
      console.log(sites);//return empty array
    })
    .catch(err=>{
      console.log("Error:",err);
    })
  },[])

方法二:

const [sites,setSites]=useState([]);
useEffect(()=>{
    getAllSites().then(res=>{
      console.log("res",res.sites);
    },(res)=>{
     setSites(res);//thought maybe because of async nature, so tried using callback but still empty 
})
    .catch(err=>{
      console.log("Error:",err);
    })
  },[])

有人可以帮我解决这个问题吗?

标签: javascriptreactjs

解决方案


react 中的状态更新不会同步发生。这意味着当您调用时setSites,状态不会得到更新,而是在下一次渲染中可以使用更改或更新的状态。

为了查看这是否有效,我们可以useEffect通过将state变量作为依赖项传递来使用钩子

const {useState, useEffect} = React;

const getAllSites = () => {
  return new Promise(res => {
    setTimeout(() => {
      return res({sites:[{id:1, name:"Google"}, {id:2, name:"Facebook"}]});
    }, 500)
  })
}

const App = () => {
  const [sites,setSites] = useState([]);
  
  useEffect(()=>{
    getAllSites().then(res=>{
      //console.log("res",res.sites);//response received successfully
      setSites(res.sites);
    })
    .catch(err=>{
      console.log("Error:",err);
    })
  },[]);
  
  useEffect(() => {
    //This will print on mount as well as when there's any change in `sites`
    console.log(sites);
  }, [sites])
  
  return <p>App</p>
}


ReactDOM.render(<App />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>

<div id="react"></div>

而且,在获取数据时,您可以显示加载指示,一旦数据可用,您可以隐藏加载并显示实际数据。


推荐阅读