在父状态改变后,子组件不会更新

时间:2017-11-25 11:56:41

标签: reactjs

我正在尝试制作一个反应消息传递应用,其中频道页面由频道栏NO(父组件)组成,其中包含一般和随机频道以及消息列表Channel.js(子组件)

目前,我可以点击频道栏,它会更改网址和ChannelMessage.js,但无论点击this.props.channelName,子组件都会显示相同的文字。我相信这是因为Link没有在子组件中被调用。我将如何更新/重新渲染子组件以使ComponentDidMount重新加载?

Channel.js

ComponentDidMount

ChannelMessages.js

export default class Channel extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        channelName: 'general'
    };
    this.handleSignOut = this.handleSignOut.bind(this);
}

...

render() {
    return (
        <div className="container">
            <div className="row">
                <div className="channel-list col-lg-2">
                    <h2>Channels</h2>
                    <ul className="list-group">
                        <li><Link to="/channel/general"
                            onClick={() => this.setState({ channelName: 'general' })}>General</Link></li>
                        <li><Link to="/channel/random"
                            onClick={() => this.setState({ channelName: 'random' })}>Random</Link></li>
                    </ul>
                    <div className="footer-segment">
                        ...
                    </div>
                </div>
                <ChannelMessages channelName={this.state.channelName} />
            </div>
        </div>
    );
}

}

1 个答案:

答案 0 :(得分:0)

为什么不直接使用道具中的channelName?您正在使用componentDidMount事件。它只运行一次。如果要在传递新通道名称时运行firebase代码;提取获取逻辑函数并在componentDidMount和componentDidUpate中运行它(如果它与前一个不同,请在此处查看)

ComponentDidMount只运行一次 - more here

ComponentDidUpdate不会在初始触发器上运行 - more here

   export default class ChannelMessages extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            message: '',
            messages: [],
            textValue: ''
        }
        ...
    }

    componentDidMount() {
        const {channelName} = this.props;

        fetchFromDb(channelName);
    }

    componentDidUpdate(prevProps) {
        if (prevProps.channelName !== this.props.channelName) {
            fetchFromDb(this.props.channelName);            
        }
    }

    componentWillUnmount() {
        this.messageRef.off('value');
    }

    handleSubmitMessage(event) {
        event.preventDefault();
        let user = firebase.auth().currentUser;
        this.messageRef.push().set({
            author: {
                displayName: user.displayName,
                photoURL: user.photoURL,
                uid: user.uid
            },
            body: this.state.message,
            createdAt: firebase.database.ServerValue.TIMESTAMP
        });
        this.setState({ message: '' });
    }

    ...

    render() {
        return (...);
    }
}