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

javascript - React Context API Seems to re-render every component - Stack Overflow

programmeradmin0浏览0评论

I'm trying to use the new Context API in my app and it looks like every time I update the context, it re-renders any component connected to it regardless. I have a sandbox demo setup to see code and working issue. When you type in the input - the buttons context is rendered and vice-versa. My original thinking was that if you type in the input, only the input context would be printed out.

DEMO

Is this how it works or am I missing something? Thanks, Spencer

I'm trying to use the new Context API in my app and it looks like every time I update the context, it re-renders any component connected to it regardless. I have a sandbox demo setup to see code and working issue. When you type in the input - the buttons context is rendered and vice-versa. My original thinking was that if you type in the input, only the input context would be printed out.

DEMO

Is this how it works or am I missing something? Thanks, Spencer

Share Improve this question asked Jul 8, 2018 at 16:13 Spencer BigumSpencer Bigum 1,9313 gold badges20 silver badges30 bronze badges 3
  • I'm not sure if I understood the problem correctly, but all components that depend on this context are rerendered. It's called ThemeContext. If you update a theme, you would expect that all themed components are updated. – Estus Flask Commented Jul 8, 2018 at 16:30
  • Ahh - Ok. So if I don't want the buttons to get re-rendered when the text changes, then do they need to have their own "CONTEXT API"? I'm coming from redux where everything is in the store, and when an item changes the whole store doesn't propagate are-render throughout every connected component. – Spencer Bigum Commented Jul 8, 2018 at 16:34
  • 1 Yes, a different context. If you need to have more control over such 'stores', Redux is likely a better option. – Estus Flask Commented Jul 8, 2018 at 16:42
Add a comment  | 

2 Answers 2

Reset to default 11

The way I avoid re-rendering with react context API:

First I write my component as pure functional component:

const MyComponent = React.memo(({
    somePropFromContext,
    otherPropFromContext, 
    someRegularPropNotFromContext  
}) => {
    ... // regular component logic
    return(
        ... // regular component return
    )
});

Then I write a function to select props from context:

function select(){
  const { someSelector, otherSelector } = useContext(MyContext);
  return {
    somePropFromContext: someSelector,
    otherPropFromContext: otherSelector,
  }
}

I have my connect HOC wrote:

function connect(WrappedComponent, select){
  return function(props){
    const selectors = select();
    return <WrappedComponent {...selectors} {...props}/>
  }
}

All together

import connect from 'path/to/connect'

const MyComponent ... //previous code

function select() ... //previous code

export default connect(MyComponent, select)

Usage

<MyComponent someRegularPropNotFromContext={something} />

Demo

Demo on codesandbox

Conclusion

MyComponent will re-render only if the specifics props from context updates with a new value, if the value is the same, it will not re-render. Also it avoid re-rendering on any other value from context that is not used inside MyComponent. The code inside select will execute every time the context updates, but as it does nothing, its ok, since no re-rendering of MyComponent is wasted.

That is the expected behaviour. Components as consumers re-renders when their provider data updates. Further more, shouldComponentUpdate hooks do not work on Consumers.

Quoting React's content API:

All Consumers that are descendants of a Provider will re-render whenever the Provider’s value prop changes. The propagation from Provider to its descendant Consumers is not subject to the shouldComponentUpdate method, so the Consumer is updated even when an ancestor component bails out of the update.

For more info check here

发布评论

评论列表(0)

  1. 暂无评论