如何在获取数据 React hook 后设置状态

How to setstate after fetch data React hook

代码 :

结果:状态中没有数据


请帮助我,谢谢!

const [dataArray, setDataArray] = useState([]);

async function fetchData() {
    try {
        setIsLoading(true);
        const response = await getNameGroup();
        setDataArray(response);
    } catch(error) {
       // handle error
    } finally {
       setIsLoading(false);
    }
}

setState 是异步的,这就是为什么您将书籍视为空数组的原因。这是引自 React docs:

The setState function is used to update the state. It accepts a new state value and enqueues a re-render of the component.

您可能在 useEffect 回调中做错了一件事。如果你的 effect returns 一个函数,React 会在需要清理的时候 运行 它。而且您不希望在清理期间调用 fetchData 中的 setState 函数,因为组件可能会被卸载。

如果您只想 fetchData 在组件安装后仅 运行 一次,这里是一个可能的解决方案:

useEffect(() => {
  // put the fetchData inside the effect
  async function fetchData() {
    setLoading(true);
    const name = await getNameGroup();
    const tmp = await getAll(name);
    console.log(tmp);
    setBooks(tmp);
    console.log(books); // may not be the same as tmp, but you will see the updated state in the next render
    setLoading(false);
  }
  fetchData();
},[]}

您应该阅读 React docs 中有关 useEffect 挂钩的更多信息。

这是一个过时的关闭问题。

调用 fetchDatauseEffect 有一个空的依赖项数组。在 useEffect 内的 fetchData 函数中,您正在尝试打印 books ,其中第一个加载是用空数组初始化的。

所有挂钩都持有对初始化它们的变量的相同引用,直到依赖关系发生变化。要获得更新的状态,它们依赖于依赖数组。由于您的依赖项数组未指定 books,因此它也不会刷新 fetchData 函数中 books 的引用。阅读有关过时关闭问题的更多信息

这就是您的 books 变量显示陈旧数据的原因。

export default function() {
    // fetch data here
    // runs only once because of empty dependency array
    useEffect(() => { 
      let isCancelled = false

       // define the fetchData inside the `useEffect` so that 
       // you can detect if the component has been unmounted      
       // using `isCancelled`
       const fetchData = async () => {
          const tmp = await getAll()

          // only update state if component isn't unmounted
          // if you try to update state on an unmounted component,
          // React will throw an error
          if (!isCancelled) {
             setIsLoading(false)
             setBooks(tmp)
          }
       }

       if (!isCancelled) {
         setIsLoading(true)
         fetchData()
       } 

       // cleanup
       return () => {
         isCancelled = true
       }
    }, [])

}

这是一个有效的示例代码,您可以申请:

const [data, setData] = useState([]); 
const [hasError, setErrors] = useState(false);

async function fetchData() {
const LibraryQuery = JSON.stringify({query: `query { species { id name description } }`});
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
const res = await fetch('http://localhost:3000/graphql',{
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    'X-CSRF-Token': token
    },
    body: LibraryQuery
});
res
    .json()
    .then(res => setData(res.data))
    .catch(err => setErrors(err));
}

useEffect(() => {
  fetchData();
}, []);