反应-设置异步响应的状态

时间:2020-10-22 23:51:22

标签: reactjs state

我想知道您是否可以在以下情况下对最佳实践进行评论:我有一个反应页面,并且正在使用异步调用来获取一些数据。在页面上,我渲染了一些返回的数据,就像这样。 (setTimeout在里面,所以我可以看到它正在加载-API也是公共的,所以您可以看到它返回的内容)

App.js

function App() {
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      fetch("https://swapi.dev/api/people/1").then((response) =>
        response.json().then((data) => {
          setData(data);
          setIsLoading(false);
          console.log(data);
        })
      );
    }, 2000);
  }, []);

  return (
    <React.Fragment>
      <p>{data.name}</p>  //will be blank until aysnc call completes.  THIS IS FINE.
      <p>{data.films[0]}</p>  //throws an error - trying to access an index that doesn't exist.  PROBLEM
    </React.Fragment>
  );
}

我找到了解决此问题的方法,但是我在代码中随处乱扔了以下内容。另外,我必须在将这些数据传递到的子组件中再次进行此操作。

<p>{isLoading ? "loading..." : data.films[0]}</p>

有人知道更好的方法或最佳做法吗?

2 个答案:

答案 0 :(得分:1)

不要使用两个状态变量,只需使用一个,并检查是否已设置。

const [data, setData] = useState();
<p>{!data ? "loading..." : data.films[0]}</p>

另外,我必须在将这些数据传递到的子组件中再次进行此操作。

也许仅在数据加载后调用子组件吗?

<div>{data && <SomeChild data={data} />}</div>

请记住,您也可以使用可选链接,在这种情况下可以提供帮助

<p>{data?.films[0]}</p>

答案 1 :(得分:0)

我的意思是在这种情况下,仅将初始状态设置为明智的设置可能有意义:

const [data, setData] = useState({
    name: '',
    films: []
});

否则,直到拥有数据,才完全不渲染: