reactjs 如何防止react组件渲染多次

wwodge7n  于 2023-02-18  发布在  React
关注(0)|答案(2)|浏览(227)

我有下面的代码,它导致我的Dashboard组件渲染了几次。我怎样才能把它减少到只有一次呢?
Jmeter 板

const Dashboard: React.FC = () => {
    const { account } = useActiveWeb3React();
    const { 
        status: status1, 
        loading: loading1, 
        error: error1, 
        response: response1, 
        payload: payload1 
    } = useAllLPTokens()
... ...

自定义钩

const useAllLPTokens = (): GraphQLResponse<LPTokens> => {
    const [status, setStatus] = useState<number>(0);
    const [loading, setLoading] = useState<boolean>(false);
    const [error, setError] = useState<any>();
    const [response, setResponse] = useState<any>();
    const [payload, setPayload] = useState<LPTokens | undefined>();

    const getLPTokenData = async () => {
        setLoading(true);
        try {
            const res = await axios.post(subgraphEndpoint,
                {
                    headers: { "Content-Type": "application/json" },
                    query: graphQuery
                }
            );
            setStatus(res.status);
            setResponse(res)
            setPayload(res.data)
        } catch (error) {
            setError(error)
        }
        setLoading(false);
    }

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

    return { status, loading, error, response, payload }
}

我猜这是因为所有的useState在自定义挂钩,我怎么能改变我的代码?

eqzww0vc

eqzww0vc1#

我猜你可以用一个钩子来存储状态,如下所示:

const [state, setState] = useState({loading: false, res: null, error: null});

  const getLPTokenData = async () => {
        setState(prev => ({...prev, loading: true}));
        try {
            const res = await axios.post(subgraphEndpoint,
                {
                    headers: { "Content-Type": "application/json" },
                    query: graphQuery
                }
            );
            setState({loading: false, res, error: null});
        } catch (error) {
            setState({loading: false, res: null, error});
        }
    }

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

  return { 
      status: state.res?.status || 0,
      loading: state.loading,
      error: state.error,
      response: state.res,
      payload: state.res?.data
  }

这样做你肯定UI批量更新,但我的建议是不要担心太多的渲染和React中的重新渲染,库本身是真的很聪明,以了解什么实际上改变了渲染和更新DOM。你张贴的代码是完美的罚款,我不会改变它。

py49o6xq

py49o6xq2#

如果使用React.strictMode,useEffect将运行两次。假设您现在使用的是非严格模式。如果添加

console.log('render', status, res);

在控制面板中。您将看到

// init render
App.js:29 render 0 undefined

// after loading status set re-render
App.js:29 render 0 undefined

// after data is resolve re-render
App.js:29 render 1243 {successResponse: true, code: '200', data: {…}, requestId: 'eD610Be4-AB3b-f9fe-DcC6-Fa2F0F612DfE', id: ''}

在这里你可以删除加载状态以减少二次渲染。根据响应设置加载组件

const ifLoading = !Boolean(res)

顺便说一句,重复的状态(状态,负载等)是无用的,总是使意外的错误。

相关问题