我有一个房间,我有一些消息。所以模型是
{
createdAt: Date,
messages: [String]
}
我用
取了我的房间class Room extends React.Component {
constructor(props) {
super(props);
this.state = { room: {} };
}
componentDidMount() {
this.fetchRoom();
}
componentDidUpdate(prevProps) {
let oldId = prevProps.params.roomId
let newId = this.props.params.roomId
if (newId !== oldId) {
this.fetchRoom();
}
}
componentWillUnmount() {
this.ignoreLastFetch = true;
}
fetchRoom() {
if (!this.ignoreLastFetch) {
const roomId = this.props.params.roomId;
socket.emit('get room', roomId, room => {
this.setState({ room: room });
});
}
}
render() {
console.log(this.state.room.messages); // debug
const roomId = this.state.room._id;
return (
<div>
<h2>Id: {roomId}</h2>
<p>Created at: {this.state.room.createdAt}</p>
<h2>Messages</h2>
<Messages roomId={roomId} messages={this.state.room.messages} />
</div>
);
}
}
问题是render()
在之前被称为我已经取出房间,之后我已经取出房间,因此它会导致2次通话。
我不能等到render
才取出房间,因为我不在乎看空房间吗?
似乎因为我使用<Messages roomId={roomId} messages={this.state.room.messages} />
,它会发送一个空数组的消息。如果我使用render()
在console.log(this.state.room.messages)
方法中调试,它首先打印undefined,然后打印消息数组(即2个调用)。
答案 0 :(得分:2)
在安装组件后将调用方法render
,但在获得所需数据之前,有一种方法不会呈现组件。 React documentation定义了如何解决这个问题:
您还可以返回null或false以表示您不想要 任何渲染的东西。
让我们在渲染方法中利用这一点:
render() {
// check if the room is set
if(!this.state.room){
// room is not set, return null so that nothing is rendered
return null;
}
// happy path - render the room
const roomId = this.state.room._id;
return (
<div>
<h2>Id: {roomId}</h2>
<p>Created at: {this.state.room.createdAt}</p>
<h2>Messages</h2>
<Messages roomId={roomId} messages={this.state.room.messages} />
</div>
);
}
答案 1 :(得分:0)
您应该将此逻辑放在“shouldComponentUpdate”中,而不是放在Render方法中。 render方法应该是纯粹的,你不应该在其中放置任何逻辑。从Component返回null也可能对Virtual Dom有站点效果。