子Reactjs组件不重新渲染

时间:2016-10-12 01:45:58

标签: reactjs

我有2个组件。

  • Youtube - 处理搜索栏和搜索结果的容器
  • YoutubeSearchResults - 暗示...显示ajax调用完成后的搜索结果

第一次,当您搜索某些内容时,结果显示正常。但是当你再次搜索(查询是否改变)时,YoutubeSearchResults不会更新(/重新渲染),尽管它的渲染函数被调用和执行(我知道因为各种console.log' s显示输出)。我无法弄清楚为什么会发生这种情况,而且搜索似乎与我所遇到的情况类似。

Youtube组件:

...
render() {
    let body = null;
    if(this.state.data !== null) {
        body = <YoutubeSearchResults data={this.state.data} />
    }
    return (
        <div>
            <div className="youtube-header">
                <form name="youtube-search" action="" onSubmit={this.search.bind(this)} method="post" ref="youtubeSearch">
                    <input type="text" name="q" placeholder="Search" autoComplete="off" />
                </form>
            </div>
            <div className="youtube-body" ref="youtubeBody">{body}</div>
        </div>
    );
}
search(e) {
    let self = this;

    ... ajax request ... }, function(data) {
        self.setState({ data: data });
    });
}

YoutubeSearchResults组件:

export default class YoutubeSearchResults extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            data: null,
            currentPage: 0,
            currentVideoId: null
        };
    }
    componentWillReceiveProps() {
        this.setState({ currentVideoId: null });
    }
    render() {
        let self = this;
        ...
        return (
            <div>
                {(this.state.data||this.props.data).map(function(obj, key) {
                    return (
                        <div key={key}>
                            <img src={obj.thumbnails.medium} className="youtube-result-thumbnail" />
                            <h3 className="youtube-result-title">{obj.title}</h3>
                            <div className="youtube-result-duration">
                                <span>{obj.contentDetails.duration.toSeconds().parseDuration()}</span>
                            </div>
                        </div>
                    );
                })}
                ...
            </div>
        );
    }
    ...
}

3 个答案:

答案 0 :(得分:0)

您需要在接收新属性时更新子组件中的状态:

componentWillReceiveProps(newProps) {
    this.setState({ currentVideoId: null, data: newProps.data });
}

此更新还将触发重新渲染。

答案 1 :(得分:0)

在React中,如果您只是需要显示某些内容而不进行修改,请避免将其存储在状态中。这增加了不必要的复杂性和渲染开销。

我删除了data的多余状态对象,并删除了不明确的(this.state.data||this.props.data)映射调用。以下代码是否适合您?

<强> YoutubeSearchResults:

export default class YoutubeSearchResults extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            currentPage: 0,
            currentVideoId: null
        };
    }
    componentWillReceiveProps() {
        this.setState({ currentVideoId: null });
    }

    render() {
        const data = this.props.data;
        // ...
        return (
            <div>
                { data.map((obj, key) => {
                    return (
                        <div key={key}>
                            <img src={obj.thumbnails.medium} className="youtube-result-thumbnail" />
                            <h3 className="youtube-result-title">{obj.title}</h3>
                            <div className="youtube-result-duration">
                                <span>{obj.contentDetails.duration.toSeconds().parseDuration()}</span>
                            </div>
                        </div>
                    );
                })}

            </div>
        );
    }
    // ...
}

答案 2 :(得分:0)

好的,我明白了。当我执行搜索时,我正在清空搜索结果容器。

search(e) {
    let self = this;

    ... ajax request ... }, function(data) {
        $(self.refs.youtubeBody).empty(); // <-- This was the issue
        self.setState({ data: data });
    });
}

不知道为什么我之前没有想到这个,但是,我认为它实际上是删除了YoutubeSearchResults组件所以当更新道具时没有设置或者其他东西。错误地将它排除在我的问题之外,因为当时我认为这不是问题。

因此,对于遇到类似问题的任何人,请确保您没有删除该组件。