简体   繁体   中英

About react.js conditional rendering,Or a potential bug in react.js?

I am working on a news feed web application and some of my code: MainContainer.js :

renderContent(source) {
        let content;
        switch (source) {
            case 'bbc':
            case 'cnn':
            case 'reuters':
                content = <Guide  source={source}/>;
                break;
            case 'medium':
                content=null;
                break;
            default:
                content = null;
                break;
        }

        return content;
    }
    render() {
        let {source} = this.props;
        return this.renderContent(source);

    }

This is code from MainContainer ,which is a container component to render different news from CNN,or BBC. Its wrapper component is App

App.js render()

 <div>
      <ScrollableTab sources={sources} handleChange={this.handleSwitchTag.bind(this)} current={current}/>
      <MainContainer source={sources[current].toLowerCase()}/>
 </div> 

When a user click some tab in ScrollableTab ,the source property of MainContainer changes,which will lead to a different Guide rendering.(After some logging, source did change in MainContainer ).

However,this failed, Guide fail to umount. Only when user clicks Medium in which case renderContent() returns null can Guide umount.

I thought,this probably because React.js cannot distiguish similar components and with some optimization,it thinks there is no need to umount the 'same' component which actually is a different one.

So,I add key= in renderContent ,I mean:

renderContent(source) {
        let content;
        switch (source) {
            case 'bbc':
            case 'cnn':
            case 'reuters':
                content = <Guide key={source} source={source}/>;
                break;
            case 'medium':
                content=null;
                break;
            default:
                content = null;
                break;
        }

        return content;
    }
    render() {
        let {source} = this.props;
        return this.renderContent(source);

    }

In this way, It works. But I cannot find any explanation in documentation of React.js. Or I just missed out some docs.Can someone tell me whether it is a bug or just over-optimization?

It's in the documentation of React , but this article from Tyler Mcginnis explains it.

The first thing React will do when setState is called is merge the object you passed into setState into the current state of the component. This will kick off a process called reconciliation . The end goal of reconciliation is to, in the most efficient way possible, update the UI based on this new state. To do this, React will construct a new tree of React elements (which you can think of as an object representation of your UI). Once it has this tree, in order to figure out how the UI should change in response to the new state, React will diff this new tree against the previous element tree.

Keys are what help React keep track of what items have changed, been added, or been removed from a list.

It's important that each key be unique among siblings. We've talked a few times already about reconciliation and part of this reconciliation process is performing a diff of a new element tree with the most previous one. Keys make this process more efficient when dealing with lists because React can use the key on a child element to quickly know if an element is new or if it was just moved when comparing trees. And not only do keys make this process more efficient, but without keys, React can't know which local state corresponds to which item on move. So never neglect keys when mapping.

You can find the complete article here React Interview Questions

When you add key prop to the Guide component, it creates a new Guide component for each new source (getInitialState method should be called in this case), and will unmount the old component as it is no longer returned by the render function. However, when no key prop is present it updates the same component with a new prop( componentWillRecieveProp method should have been called in this case). The same Guide component is returned by the render method with a new prop and hence should not be unmounted.

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