当状态改变时,如何使反应组件重新渲染?

时间:2021-02-03 01:39:50

标签: javascript json reactjs

正如你在这里看到的。我首先进行 API 调用以从服务器获取我的数据使用情况,然后通过设置 setDataUsage 将我从服务器获得的响应存储到 dataUsage。但是,我从未在“{ name: 'Used', data: usedPercent }” 中获得准确的 usedPercent,相反,我收到了零。在 API 调用完成后,如何确保此组件进行更新和重新渲染?

const Piechart= () => {
    const userContext = useContext(UserContext)
    const history = useHistory()
    const [dataUsage, setDataUsage] = useState({
        upload: 0,
        redundancy: 0,
        usedData: 0,
        downloaded: 0,
        quoteData: 0,
        rank: 0
    });
    const [usedPercent, setUsedPercent] = useState(0);
  

    useEffect(() => {
        API().get('/mydatausage')
          .then(res => {
            const usage = res.data;
            setDataUsage({ upload:usage.up, redundancy:usage.red, usedData:usage.used, 
                downloaded:usage.dwn, quoteData:usage.quote, rank:usage.rnk });
          }).catch(err => {
            authErrorHandler(err, userContext.logoutHandler, history)
          })
      },[])

      const bToGbIndex = 1073741824;

      useEffect(
        () => {
          // if (componentDidUpdate & (x or y changed))
          setUsedPercent(dataUsage.usedData / bToGbIndex / dataUsage.quoteData);
        },
        [dataUsage]
      );

      const unUsedPercent = 100 - usedPercent;

      console.log(usedPercent)
      console.log(unUsedPercent)


  return(
    <>  
        <Donut
            chartData={[
                { name: 'Used', data:  usedPercent },
                { name: 'Free', data:  unUsedPercent }
            ]}
            chartWidth={300}
            chartHeight={500}
            title="Your Data Usage"
            chartThemeConfig={{
                series: {
                    colors: ['#ffe0bd', '#670303', '#6cbfce'],
                },
            }}
        />
    </>
  );
}

export default Piechart

2 个答案:

答案 0 :(得分:0)

您的 usedPercent 可以只是组件内的一个简单变量:

const usedPercent = dataUsage.quoteData ? (dataUsage.usedData / bToGbIndex / dataUsage.quoteData) : 0;

或者如果你想记住它(它是可选的),使用 React useMemo 钩子:

const { usedData, quoteData } = dataUsage;
const usedPercent = useMemo(() => quoteData ? (usedData / bToGbIndex / quoteData) : 0, [usedData, quoteData]);

您不需要单独的 useEffect 来更新 usedPercent。将 useEffect 视为旧的 componentDidUpdate / componentDidMount,虽然可以在 componentDidUpdate 中执行多项操作,但它们不应相互依赖。避免编写依赖于他人的 useEffect 语句。

事实上,由于您的 usedPercent 是从 dataUsage 派生/计算的数据,因此您也不必将其设为有状态变量。如果您想让 React 组件保持简单和可维护,请始终尽量将有状态数据的数量保持在最低限度。

答案 1 :(得分:0)

看起来您在渲染组件时同时使用了 usedPercent and unUsedPercent

<Donut chartData={[
                { name: 'Used', data:  usedPercent },
                { name: 'Free', data:  unUsedPercent }
            ]}
       ...

因此,当您将 usedPercent 设为零时,实际状态不会改变,因此组件不会重新渲染\更新。

由于您使用的是 usedPercent and unUsedPercent,因此我会为 unUsedPercent 创建一个状态变量,那么您的使用效果应如下设置,以便您的组件即使在您获得 usedPercent as zero 时也会更新

const [unUsedPercent, setUnUsedPercent] = useState(0);

      useEffect(
        () => {
          // if (componentDidUpdate & (x or y changed))
          setUsedPercent(dataUsage.usedData / bToGbIndex / dataUsage.quoteData);
          const unUsedPercent = 100 - usedPercent;
          serUnUnsedPercent(unUsedPercent);
        },
        [dataUsage]
      );