简体   繁体   中英

How do I make react component rerender when the State is changed?

As you can see here. I first make an API call to get my data usage from the server, and then I store the response I got from the server to dataUsage by setting setDataUsage. However, I never got the accurate usedPercent in "{ name: 'Used', data: usedPercent }", instead, I received a zero. How do I make sure this component takes the update and rerender once the API call has been finished?

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

Your usedPercent can just be a simple variable inside the component:

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

Or if you want to memoize it (it's optional), use the React useMemo hook:

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

You don't need to have a separate useEffect to update usedPercent . Think about useEffect as the old componentDidUpdate / componentDidMount , while it's possible to do multiple things inside componentDidUpdate , they shouldn't be dependent of each other. Avoid writing useEffect statements those are dependent of others.

In fact, as your usedPercent is derived / computed data from dataUsage , you don't have to make it a stateful variable either. If you want to keep your React component simple and maintainable, always try to keep the number of stateful data to minimum.

Looks like you are using both usedPercent and unUsedPercent while rendering the component.

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

So when you get usedPercent as zero then actaual state is not changed so component does not re-render\update.

Since you are using usedPercent and unUsedPercent , I would create one state variable even for unUsedPercent then your use effect should set this as below so that your component gets updated even when you get 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]
      );
  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM