简体   繁体   中英

Using ContextAPI doesn't re-render its consumer, but content is changed. Why?

Consider this little example. I did some experiments with Context API while learning through the book.

const MyContext = React.createContext(0);

const D3 = () => {
    console.log('render D3');
    return <MyContext.Consumer>{num => `${num}`}</MyContext.Consumer>;
};

const D2 = React.memo(() => {
    console.log('render D2');
    return <D3 />;
});

const D1 = React.memo(() => {
    console.log('render D1');
    return <D2 />;
});

const App = () => {
    const [num, setNum] = useState(0);

    console.log('render App');
  return (
    <div>
      <MyContext.Provider value={num}>
        <D1 />
      </MyContext.Provider>
      <input type='button' onClick={() => { setNum(Math.random()) }} />
    </div>);
};

ReactDOM.render(<App />, document.querySelector('#root'));

As I click the button, I can see my tiny number is changing. Also notice that App is rendered for each click while D1 , D2 are not. I understood the reason of this.

But weird thing is, when button is clicked, D3 hasn't been re-rendered. Still its content is changing? What happened exactly?

Please check this for your convinient: https://jsfiddle.net/gfnuko/cs7jpo69/4/

The child <MyContext.Consumer> is re-rendered. Do this to see:

const D3 = () => {
    console.log('render D3');
    return <MyContext.Consumer>{num => {console.log('CONSUMER'}; return num;}}</MyContext.Consumer>;
};

Fiddle

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