Я создаю приложение чата с socket.io, и у меня есть компонент панели мониторинга с двумя дочерними компонентами, который называется Room.js и Chat.js.Компонент «Моя комната» отвечает за выбор комнаты чата, в которую вы хотите вступить.В теге select я даю ссылку, чтобы узнать значение.Как мне получить доступ к этому значению в моем компоненте чата, чтобы я мог отправлять сообщения только в этой комнате?
Я разместил рабочую версию ниже первого фрагмента с сообщениями и всем в одном компоненте, но мне нужно, чтобы они былиотдельные компоненты.
Я все еще новичок в реакции.
class Room extends Component {
constructor(props) {
super(props);
this.state = {
};
this.joinRoom = this.joinRoom.bind(this);
this.joinSuccess = this.joinSuccess.bind(this);
}
componentDidMount() {
this.socket = io("http://localhost:4444")
this.socket.on('message dispatched', this.updateMessages)
this.socket.on('welcome', this.setUserId)
this.socket.on('room joined', this.joinSuccess)
this.joinRoom()
}
joinRoom() {
this.socket.emit('join room', {
room: this.refs.room.value
})
}
joinSuccess(room) {
console.log("you successfully joined room " + room)
}
render() {
return (
<Background>
<Container className="animated fadeInDownBig">
{" "}
<Logo> Sketchful </Logo>
<Info>Join a Room</Info>
<select ref='room' defaultValue='Global' onChange={this.joinRoom}>
<option>Global</option>
<option>Stark</option>
<option>Lannister</option>
<option>Targaryen</option>
<option>Tyrell</option>
<option>Baratheon</option>
<option>Greyjoy</option>
</select>
<Link to="/dashboard">
<Button onClick={this.props.handleEnter}> Enter </Button>
</Link>{" "}
</Container>
</Background>
);
}
}
export default Room;
Если я сделаю это, это сработает, но я хочу, чтобы компонент Chat отвечал за отправку сообщений.
class Room extends Component {
constructor(props) {
super(props);
this.state = {
messages: [],
};
this.updateMessages = this.updateMessages.bind(this);
this.sendMessage = this.sendMessage.bind(this);
this.joinRoom = this.joinRoom.bind(this);
this.joinSuccess = this.joinSuccess.bind(this);
}
componentDidMount() {
this.socket = io("http://localhost:4444")
this.socket.on('message dispatched', this.updateMessages)
this.socket.on('welcome', this.setUserId)
this.socket.on('room joined', this.joinSuccess)
this.joinRoom()
}
updateMessages(message) {
const updatedMessages = this.state.messages.slice()
updatedMessages.push(message)
this.setState({
messages: updatedMessages
})
}
sendMessage() {
this.socket.emit('message sent', {
message: this.refs.message.value,
room: this.refs.room.value
})
this.refs.message.value = '';
}
joinRoom() {
this.socket.emit('join room', {
room: this.refs.room.value
})
}
joinSuccess(room) {
console.log("you successfully joined room " + room)
}
render() {
const messages = this.state.messages.map((e,i) => {
const styles = e.user === this.state.userID ? {alignSelf: "flex-end", backgroundColor: "#2d96fb", color: "white"} : {alignSelf: "flex-start", backgroundColor: "#e5e6ea"}
return (
<p key={i} style={styles}>{e.message}</p>
)
})
console.log(this.props.room)
return (
<Background>
<Container className="animated fadeInDownBig">
{" "}
<Logo> Sketchful </Logo>
<Info>Join a Room</Info>
<select ref={this.props.room} defaultValue='Global' onChange={this.joinRoom}>
<option>Global</option>
<option>Stark</option>
<option>Lannister</option>
<option>Targaryen</option>
<option>Tyrell</option>
<option>Baratheon</option>
<option>Greyjoy</option>
</select>
<div className="messages">
{messages}
</div>
<div className="input">
<input ref="message" />
<button onClick={this.sendMessage}>Send</button>
</div>
<Link to="/dashboard">
<Button onClick={this.props.handleEnter}> Enter </Button>
</Link>{" "}
</Container>
</Background>
);
}
}
export default Room;
class Chat extends Component {
constructor(props) {
super(props);
this.state = {
// words: ["cat", "dog", "sun", "cup", "pie", "bug", "snake", "tree"],
messages: [],
message: "",
correct: '',
typing: false,
timeout: undefined,
};
// this.socket = io.connect("http://localhost:4444");
this.handleEnter = this.handleEnter.bind(this)
}
componentDidMount() {
this.socket = io.connect("http://localhost:4444");
this.socket.on("chat", msg => {
let messages = this.state.messages
messages.push(msg)
this.setState({
messages: messages
})
});
}
componentWillUnmount() {
this.socket.close();
}
updateMessage = e => {
this.setState({
message: e.target.value
});
};
async handleEnter (e) {
if(this.state.message) {
if (e.key === "Enter" ) {
this.socket.emit("chat", {
name: this.props.user.username,
message: this.state.message,
timestamp: new Date().toISOString(),
});
this.setState({
message: ""
});
const response = await axios.post(`/api/create`, {message: this.state.message})
this.props.getUserData(response)
let words = this.props.words;
for (let i = 0; i < words.length; i++) {
if (this.state.message === this.props.word) {
this.setState({
correct: 'Correct!'
})
}
}
}
}
};
handleClick = () => {
console.log('clicked')
}
render() {
console.log(this.state.message)
return (
<div className="chat">
<Messages messages={this.state.messages} user={this.props.user.username}/>
<p>{this.state.correct}</p>
<textarea
value={this.state.message}
onKeyPress={this.handleEnter}
onChange={this.updateMessage}
className="message"
placeholder="Type a message... "
type="text"
/>
</div>
);
}
}
function mapStateToProps(state) {
return {
user: state.user,
id: state.id
};
}
export default connect(
mapStateToProps,
{ getUserData }
)(Chat);
Сервер
io.on("connection", socket => {
console.log("a user connected");
socket.on("disconnect", function() {
console.log("user disconnected");
});
socket.on('join room', data => {
console.log('Room joined', data.room)
socket.join(data.room);
io.to(data.room).emit('room joined', data.room);
})
socket.on("chat", data => {
console.log(data.room)
io.in(data.room).emit("chat", data);
});