Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - How do i force child components to re render when parent state component changes?

in my pen http://codepen.io/seunlanlege/pen/PbYNor?editors=0010#0

what's happening is pretty simple. when the this.send() method is called. this.state.chat is sent to child component <Messages /> which is then concatenated to thethis.state.messages` array and rendered.

but the thing is, 1second after rendering i update this.state.sent which is a prop of <Messages /> but messages component doesn't re-render.

please how do i force it to re-render?

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>
like image 682
Seun LanLege Avatar asked Feb 06 '23 19:02

Seun LanLege


1 Answers

your codepen is alomost fine, only thing you missed is proper key for message component,

for react to render components properly each component should have different key, so i changed the piece of code from

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

To

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

and code-pen worked fine

EDIT this solves the propblem

instead of saving the components to state, dynamically build them. check this codepen.io/abhirathore2006/pen/JbjjPx

like image 162
abhirathore2006 Avatar answered Feb 09 '23 03:02

abhirathore2006