【问题标题】:React - How do i force child components to re render when parent state component changes?React - 当父状态组件更改时,如何强制子组件重新渲染?
【发布时间】:2016-11-03 09:36:41
【问题描述】:

在我的笔下http://codepen.io/seunlanlege/pen/PbYNor?editors=0010#0

发生的事情非常简单。当this.send() 方法被调用时。 this.state.chat 被发送到子组件 <Messages /> which is then concatenated to thethis.state.messages` 数组并被渲染。

但问题是,渲染后 1 秒我更新了 this.state.sent,这是 <Messages /> 的一个属性,但消息组件不会重新渲染。

请问如何强制重新渲染?

class Messages extends React.Component{
constructor(props){
super(props);
}
render(){
return(
`<p id={this.props.key} className={this.props.style}>{this.props.msg}<span>{this.props.sent}</span></p>`);
}
}


class Chat extends React.Component {
constructor(props) {
super(props);
this.count = 0;
    this.state = {chat :'',messages:[],sent:[]}; 
}
chatChange(event){
    this.setState({chat : event.target.value});
}
send(e){
    e.preventDefault();
    let x = this.state.messages;
    this.setState({messages:x.concat([<Messages style="me" msg={this.state.chat} key={this.state.chat} sent={(this.state.sent[this.count])?this.state.sent[this.count]:''} />])});
this.setState({chat:''});
setTimeout(()=>{
  this.setState({sent:this.state.sent.concat(['sent'])});
  this.count++;
},1000);
}
render () {
    return(
        `<div>
        <div id="top"><h1>Chat With Customer Support</h1></div>
        <div id="chatbox">
        {this.state.messages}
        </div>
        <div id="bottom">
        <form onSubmit={this.send.bind(this)}>
        <span>
        <input value={this.state.chat} type="text" onChange={this.chatChange.bind(this)} id="chat" value={this.state.chat} />
        <button type="submit" id="send">Send</button>
        </span>
        </form>
        </div>
        </div>`
        );
}
}ReactDOM.render(<Chat name="seun" />,document.getElementById('app')):</code>

【问题讨论】:

  • 消息框确实在更新这里的问题是,当您提交相同的文本时它不会更新,因为 React 将更改视为消息的虚拟 DOM 中已经存在的元素。你应该做的是为每条消息添加一个 id。

标签: javascript reactjs ecmascript-6


【解决方案1】:

您的 codepen 几乎没问题,唯一错过的是消息组件的正确键,

为了正确渲染组件,每个组件应该有不同的键,所以我改变了这段代码

<Messages style="me" msg={this.state.chat} key={this.state.chat} sent={(this.state.sent[this.count])?this.state.sent[this.count]:''} />

<Messages style="me" msg={this.state.chat} key={this.count} sent={(this.state.sent[this.count])?this.state.sent[this.count]:''} />

code-pen 工作正常

编辑 这样就解决了问题

不是将组件保存到状态,而是动态构建它们。检查这个codepen.io/abhirathore2006/pen/JbjjPx

【讨论】:

  • 但是当this.state.sent被修改时&lt;Message /&gt;组件不会重新渲染
  • 不是将组件保存到状态,而是动态构建它们。检查这个codepen.io/abhirathore2006/pen/JbjjPx
【解决方案2】:

将此作为组件的键

 this.state.messages.length

React 不允许您使用相同的键输入两个元素。这就是 react 虚拟 DOM 在重新渲染时区分变化的方式

【讨论】:

    【解决方案3】:

    componentWillReceiveProps 应该采用 nextProps。

    【讨论】:

    【解决方案4】:

    每当整个组件重新渲染时,React 都会将所有组件与之前的状态/键匹配。因此,如果您在每次父级重新渲染时为子级提供唯一键,则子级也将重新渲染。

    Lodash 提供了一个函数_.uniqueId(),每次调用都会生成一个唯一的id。

    <Parent>
        <Child key={_.uniqueId('child_component')} />
    </Parent>
    

    【讨论】:

      猜你喜欢
      • 2019-01-08
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 1970-01-01
      • 1970-01-01
      • 2018-08-14
      • 1970-01-01
      • 2022-06-29
      相关资源
      最近更新 更多