【问题标题】:How to rerender function component when id changed in url当 url 中的 id 更改时如何重新渲染功能组件
【发布时间】:2020-04-24 13:26:08
【问题描述】:

我有一个 React 组件,它从 IndexedDB 获取一些数据,这是一个异步任务,它使用 useParams 钩子传入的 url 中的 id,假设 id = 1。 当我点击示例中的链接时,id 变为 2,但此时没有任何反应,组件不会重新渲染。

我需要做什么才能让它工作?我只是不明白为什么它现在不起作用。 有人能启发我吗?

import React, {useState} from 'react';
import { Link, useParams } from "react-router-dom";
import { useAsync } from 'react-async';

export default function (props) {
  let {id} = useParams();
  const {data, error, isLoading} = useAsync({ promiseFn: loadData, id: parseInt(id)});
  if (isLoading) return "Loading...";
  if (error) return `Something went wrong: ${error.message}`;
  if (data)
   return (
    <>
      <h1>{data.name}</h1>
      <Link to={'/2'}>other id</Link>
    </>
   );
}

【问题讨论】:

    标签: reactjs indexeddb react-router-v5 react-async


    【解决方案1】:

    异步函数应该在 useEffect 钩子内调用。 useEffect 将始终在 id 更改时被调用。

    import React, { useState } from "react";
    import { Link, useParams } from "react-router-dom";
    import { useAsync } from "react-async";
    
    export default function(props) {
      let { id } = useParams();
    
      const [error, setError] = useState(null);
      const [isLoading, setIsLoading] = useState(false);
      const [data, setData] = useState(null);
    
      useEffect(() => {
        const { data, error, isLoading } = useAsync({
          promiseFn: loadData,
          id: parseInt(id)
        });
        setIsLoading(isLoading);
        setError(error);
        setData(data)
      }, [id]);
    
      if (isLoading) return "Loading...";
      if (error) return `Something went wrong: ${error.message}`;
      if (data)
        return (
          <>
            <h1>{data.name}</h1>
            <Link to={"/2"}>other id</Link>
          </>
        );
    }
    

    【讨论】:

    • 我尝试了这段代码,但在 if 语句和下面的语句中无法访问数据、错误和 isLoading 变量。是否需要使用 useState 在 useEffect 函数中设置一些状态?
    • 是的,您将无法在 useEffect 之外访问它,因为它是 const 被阻止的范围。您需要使用 useState 将值存储在状态中
    • Jagrati 谢谢。您的回答并没有完全解决我的问题,但您为我指明了正确的方向。该问题与 react-async 库中的 useAsync 有关。看起来 useAsync 函数已经使用了 useEffect 函数。当我从 useEffect 函数调用 loadData 函数时,一切正常。
    【解决方案2】:

    使用 react-async 库中的 useAsync 钩子时,您可以使用 watch 或 watchFn 选项来监视更改。所以更改以下行:

    const {data, error, isLoading} = useAsync({ promiseFn: loadData, id: parseInt(id)});
    

    到:

    const {data, error, isLoading} = useAsync({ promiseFn: loadData, id: parseInt(id), watch: id});
    

    成功了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-14
      • 2019-08-09
      • 2023-03-20
      • 2020-08-23
      • 2021-12-22
      • 2021-03-15
      • 2021-01-27
      • 2021-07-08
      相关资源
      最近更新 更多