【问题标题】:How to setstate after fetch data React hook [duplicate]获取数据后如何设置状态反应钩子
【发布时间】:2020-10-02 09:10:09
【问题描述】:

代码:

结果:状态中没有数据


请帮帮我,谢谢!

【问题讨论】:

  • 书籍默认为 [] 。 "const [books, setBooks] = useState([]);"
  • 如果你在函数中console.log(tmp)会得到什么?
  • 请在下次直接复制粘贴或输入实际代码或消息。它帮助别人帮助你。 ;)

标签: reactjs react-hooks setstate


【解决方案1】:

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

setState 函数用于更新状态。它接受一个新的 状态值和入队组件的重新渲染。

您可能做错的一件事是在您的useEffect 回调中。如果你的效果返回一个函数,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 挂钩的更多信息。

【讨论】:

    【解决方案2】:
    const [dataArray, setDataArray] = useState([]);
    
    async function fetchData() {
        try {
            setIsLoading(true);
            const response = await getNameGroup();
            setDataArray(response);
        } catch(error) {
           // handle error
        } finally {
           setIsLoading(false);
        }
    }
    

    【讨论】:

      【解决方案3】:

      这是一个陈旧的关闭问题。

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

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

      这就是您的 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
             }
          }, [])
      
      }
      

      【讨论】:

        【解决方案4】:

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

        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();
        }, []);
        

        【讨论】:

          猜你喜欢
          • 2020-03-19
          • 1970-01-01
          • 1970-01-01
          • 2020-11-30
          • 1970-01-01
          • 1970-01-01
          • 2021-04-10
          • 2020-07-31
          相关资源
          最近更新 更多