我正在尝试制作一个反应消息应用程序,其中频道页面由一个频道栏Channel.js
(父组件)和一个通用和随机频道和一个消息列表ChannelMessage.js
(子组件)组成。
目前,我可以单击频道栏并更改 url 和this.props.channelName
,但是子组件显示相同的文本,无论是否Link
单击。我相信这是因为ComponentDidMount
在子组件中没有被调用。我将如何更新/重新渲染子组件以使 ComponentDidMount 重新加载?
频道.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>
);
}
频道消息.js
export default class ChannelMessages extends React.Component {
constructor(props) {
super(props);
this.state = {
channelName: this.props.channelName,
message: '',
messages: [],
textValue: ''
}
...
}
componentWillReceiveProps(nextProps) {
this.setState({channelName: nextProps.channelName})
}
componentDidMount() {
this.messageRef = firebase.database().ref('messages/' + this.state.channelName);
this.messageRef.limitToLast(500).on('value', (snapshot) => {
let messages = snapshot.val();
if (messages !== null) {
let newMessages = [];
for (let message in messages) {
newMessages.push({
author: {
displayName: messages[message].author.displayName,
photoURL: messages[message].author.photoURL,
uid: messages[message].author.uid
},
body: messages[message].body,
createdAt: messages[message].createdAt,
id: message
});
}
this.setState({ messages: newMessages, textValue: newMessages.body });
}
console.log(this.state.textValue)
});
}
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 (...);
}
}
为什么不直接从道具中使用 channelName ?您正在使用 componentDidMount 事件。它只运行一次。如果您想在传递新频道名称时运行 firebase 代码;提取获取逻辑函数并在componentDidMount和componentDidUpate中运行(检查这里是否与之前的不同)
ComponentDidMount 只运行一次 -更多在这里
ComponentDidUpdate 不会在初始触发器上运行 -更多信息在这里
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 (...);
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句