如何解决上下文中过多的重新渲染问题? [英] How to solve problem with too many re-renders in context?

查看:42
本文介绍了如何解决上下文中过多的重新渲染问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我在上下文中更新 users ( array )中的 user ( object )时,所有使用 users 重新呈现.

Whenever I update user (object) in users (array) in context - all components which uses users re-renders.

我有一个使用上下文中值的组件:

I've component which is using values from context:

const DashboardCardList=()=> {
    const context = useContext(StaticsContext);
    const users = context.users.filter(user=>user.visible);

    return !users
        ? <Loading/>
        : (
            <Container>
                {users.map(user=>
                    <DashboardCard key={user._id} user={user}/>
                )}
            </Container>
        );
};

我的更新功能(更新上下文状态):

My update function (updates context state):

const onUserUpdate=(user)=>{
   const index = this.state.users.findIndex(item => item._id === user._id);
   const users = [...this.state.users]
   users[index] = user;
   this.setState({users:users});
}

最终组成部分:

const DashboardCard=({user})=> {
    console.log("I'm here!", user);
    return ...;
}


问题

为什么要保持重新渲染?是因为上下文吗?
如何正确编写?

推荐答案

没有针对上下文使用者( v17 )的渲染救援.

There is no render bailout for context consumers (v17).

这是一个演示,其中 Consumer 总是会重新渲染,即使他不消费任何东西也是如此.

Here is a demonstration, where the Consumer will always re-render just because he is a Context Consumer, even though he doesn't consume anything.

import React, { useState, useContext, useMemo } from "react";
import ReactDOM from "react-dom";

// People wonder why the component gets render although the used value didn't change
const Context = React.createContext();

const Provider = ({ children }) => {
  const [counter, setCounter] = useState(0);
  const value = useMemo(() => {
    const count = () => setCounter(p => p + 1);
    return [counter, count];
  }, [counter]);
  return <Context.Provider value={value}>{children}</Context.Provider>;
};

const Consumer = React.memo(() => {
  useContext(Context);
  console.log("rendered");
  return <>Consumer</>;
});

const ContextChanger = () => {
  const [, count] = useContext(Context);
  return <button onClick={count}>Count</button>;
};

const App = () => {
  return (
    <Provider>
      <Consumer />
      <ContextChanger />
    </Provider>
  );
};

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

要修复它:

  • 为每个消耗的值使用单个上下文.这意味着上下文具有单个值,(不,应用程序中的多个上下文没有问题.)
  • 使用诸如Recoil.js,Redux,MobX等之类的状态管理解决方案(尽管可能有些过分,但请事先考虑一下应用程序设计).
  • 次要优化可以通过 useMemo .
  • Use a single context for each consumed value. Meaning that context holds a single value, (and no, there is no problem with multiple contexts in an application).
  • Use a state management solution like Recoil.js, Redux, MobX, etc. (although it might be overkill, think good about app design beforehand).
  • Minor optimization can be achieved by memoizing Provider's values with useMemo.

这篇关于如何解决上下文中过多的重新渲染问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆