最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - How can I prevent unnecessary re-renders of sibling components in React when only one state value changes? - Stack Ove

programmeradmin2浏览0评论

I'm working on a React component setup where I have a parent component <MyComponent> that receives three state values, and three separate controller components that each initialize with one of these values and a setter function.

Here's a simplified version of my code.

// Parent Component
<MyComponent
  input_a={A}
  input_b={B}
  input_c={C}
/>

// State declarations
const [A, setA] = useState(1);
const [B, setB] = useState(1);
const [C, setC] = useState(1);

// Controller Components
<ElementA
  initial={A}
  setter={setA}
/>
<ElementB
  initial={B}
  setter={setB}
/>
<ElementC
  initial={C}
  setter={setC}
/>

In this setup, when I update one state value (for example, using setA), all three controller components (ElementA, ElementB, and ElementC) re-render—even though only the controller associated with the updated state should be affected. The state values serve as initial values for the controller components, and subsequent updates should ideally only affect <MyComponent>.

I have considered using memoization (such as with React.memo), but it hasn't produced the desired effect in this case. I'm looking for an alternative approach or best practices to restructure or optimize the code so that only the component corresponding to the updated state re-renders, without relying on memoization.

upd: Thank you for your answers and suggestions. I finally decided to use MobX to manage my states, and it has made my life easier.

I also realized that I had been using memoization incorrectly, but even after fixing it, I still noticed some freezing in my animations.

I'm working on a React component setup where I have a parent component <MyComponent> that receives three state values, and three separate controller components that each initialize with one of these values and a setter function.

Here's a simplified version of my code.

// Parent Component
<MyComponent
  input_a={A}
  input_b={B}
  input_c={C}
/>

// State declarations
const [A, setA] = useState(1);
const [B, setB] = useState(1);
const [C, setC] = useState(1);

// Controller Components
<ElementA
  initial={A}
  setter={setA}
/>
<ElementB
  initial={B}
  setter={setB}
/>
<ElementC
  initial={C}
  setter={setC}
/>

In this setup, when I update one state value (for example, using setA), all three controller components (ElementA, ElementB, and ElementC) re-render—even though only the controller associated with the updated state should be affected. The state values serve as initial values for the controller components, and subsequent updates should ideally only affect <MyComponent>.

I have considered using memoization (such as with React.memo), but it hasn't produced the desired effect in this case. I'm looking for an alternative approach or best practices to restructure or optimize the code so that only the component corresponding to the updated state re-renders, without relying on memoization.

upd: Thank you for your answers and suggestions. I finally decided to use MobX to manage my states, and it has made my life easier.

I also realized that I had been using memoization incorrectly, but even after fixing it, I still noticed some freezing in my animations.

Share Improve this question edited Feb 17 at 22:57 Антон Пименов asked Feb 1 at 22:43 Антон ПименовАнтон Пименов 751 silver badge6 bronze badges 4
  • Have you thought about using ref instead of state? – HairyHandKerchief23 Commented Feb 1 at 22:55
  • How exactly are you determining component "rerenders"? Based on what you have shared I don't see anything that would cause sibling components to render unnecessarily. "I'm looking for an alternative approach or best practices to restructure or optimize the code so that only the component corresponding to the updated state re-renders, without relying on memoization." - This is subjective and off-topic for Stack Overflow. Can you edit to clarify the actual problem you are seeing, and include a complete minimal reproducible example and exact reproduction steps? – Drew Reese Commented Feb 1 at 23:37
  • I think there's a misconception here. Whenever a Component's state gets updated, this Component will re-render, including ALL of its child Components unconditionally by defauly. From your code it is not clear whether all the components (and state) reside in one Component, but if they do, then it doesn't matter which state you update (A, B or C). Once one or more of these state variables change to a new value, the whole Component will re-render, including ALL 3 Element components. – Kostas Minaidis Commented Feb 2 at 0:17
  • Using React.memo(function ElementA(...)) { ... } should make ElementA rerender only when its own hooks, context or props change, even if its parent rerenders. Perhaps in your case you are passing a new callback to it each time, instead of using useCallback? – cbr Commented Feb 2 at 20:15
Add a comment  | 

1 Answer 1

Reset to default 1

By default, any change in state in a parent component will re-render the children.

setState enqueues changes to the component state. It tells React that this component and its children need to re-render with the new state. This is the main way you’ll update the user interface in response to interactions.

https://react.dev/reference/react/Component#shouldcomponentupdate

What you could do is create a React class with the shouldComponentUpdate method. This allows you granular control of how an update re-renders your component. You're in complete control here.

So in this case, unless ElementA's A prop is changed, it won't re-render. You could do the same for the others.

class ElementA extends Component {
    shouldComponentUpdate (nextProps) {
      // Rendering the component only if
      // passed props value is changed

      return nextProps.A !== this.props.A;
    }
    render() {

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论