Answer the question
In order to leave comments, you need to log in
How to correctly render a component based on state in React?
I have a chat component:
import React from "react";
import io from "socket.io-client";
class Chat extends React.Component{
constructor(props){
super(props);
this.state = {
username: '',
message: '',
messages: []
};
this.socket = io('localhost:5000');
this.socket.on('RECEIVE_MESSAGE', function(data){
addMessage(data);
});
const addMessage = data => {
console.log(data);
this.setState({messages: [...this.state.messages, data]});
console.log(this.state.messages);
};
this.sendMessage = ev => {
ev.preventDefault();
this.socket.emit('SEND_MESSAGE', {
author: this.state.username,
message: this.state.message
})
this.setState({message: ''});
}
}
render(){
return (
<div className="container">
<div className="row">
<div className="col-4">
<div className="card">
<div className="card-body">
<div className="card-title">Global Chat</div>
<hr/>
<div className="messages">
{this.state.messages.map(message => {
return (
<div>{message.author}: {message.message}</div>
)
})}
</div>
</div>
<div className="card-footer">
<input type="text" placeholder="Username" value={this.state.username} onChange={ev => this.setState({username: ev.target.value})} className="form-control"/>
<br/>
<input type="text" placeholder="Message" className="form-control" value={this.state.message} onChange={ev => this.setState({message: ev.target.value})}/>
<br/>
<button onClick={this.sendMessage} className="btn btn-primary form-control">Send</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Chat;
const ChatComponent = () => {
return (
<div className="container">
<div className="row">
<div className="col-4">
<div className="card">
<div className="card-body">
<div className="card-title">Chat</div>
<hr/>
<div className="messages">
{this.state.messages.map(message => {
return (
<div>{message.author}: {message.message}</div>
)
})}
</div>
</div>
<div className="card-footer">
<input type="text" placeholder="Message" className="form-control"/>
<br/>
<button onClick={ this.sendMessage} className="btn btn-primary form-control">Send</button>
</div>
</div>
</div>
</div>
</div>
);
}
const JoinComponent = () => {
return (
<div className="card-footer">
<input type="text" placeholder="Username" className="form-control"/>
<br/>
<button onClick={this.Join} className="btn btn-primary form-control">Join chat</button>
</div>
);
}
render() {
const username = this.state.username;
return (
<div>
{this.state.username ? (
<ChatComponent/>
) : (
<JoinComponent />
)};
</div>
);
}
Answer the question
In order to leave comments, you need to log in
Read about props and the documentation in general.
The solution to your problem in my vision:
import React from "react";
import io from "socket.io-client";
class ChatComponent extends React.Component {
state = { message: "" }
render() {
return (
<div className="container">
<div className="row">
<div className="col-4">
<div className="card">
<div className="card-body">
<div className="card-title">Chat</div>
<hr />
<div className="messages">
{this.props.messages.map(message => {
return (
<div>{message.author}: {message.message}</div>
)
})}
</div>
</div>
<div className="card-footer">
<input
type="text"
placeholder="Message"
className="form-control"
value={this.state.message}
onChange={ev => this.setState({ message: ev.target.value })} />
<br />
<button onClick={() => this.props.sendMessage(this.state.message)} className="btn btn-primary form-control">Send</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
class JoinComponent extends React.Component {
state = { username: "" }
render() {
return (
<div className="card-footer">
<input
type="text"
placeholder="Username"
className="form-control"
value={this.state.username}
onChange={ev => this.setState({ username: ev.target.value })} />
<br />
<button onClick={() => this.props.click(this.state.username)} className="btn btn-primary form-control">Join chat</button>
</div>
);
}
}
class Chat extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
messages: []
};
this.socket = io('localhost:5000');
this.socket.on('RECEIVE_MESSAGE', function (data) {
addMessage(data);
});
const addMessage = data => {
console.log(data);
this.setState({ messages: [...this.state.messages, data] });
console.log(this.state.messages);
};
}
sendMessage = (message) => {
this.socket.emit('SEND_MESSAGE', {
author: this.state.username,
message: message
})
this.setState({ message: '' });
}
joinToChat = (username) => {
this.setState({ username })
}
render() {
if (this.state.username) {
return <ChatComponent
messages={this.state.messages}
sendMessage={this.sendMessage} />}
else return <JoinComponent click={this.joinToChat} />
}
}
export default Chat;
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question