簡體   English   中英

如何從傳遞到其同級組件的下拉框中獲取ref值?

[英]How do I get the ref value from a drop down box passed to its sibling component?

我正在使用socket.io構建一個聊天應用程序,並且有一個儀表板組件,其中包含2個子組件,分別稱為Room.js和Chat.js。 我的房間組件負責選擇要加入的聊天室。 在選擇標簽中,我給它提供了一個參考來了解該值。 我將如何在“聊天”組件中訪問該值,以便僅在該房間中發出消息?

我在第一個代碼片段的下方發布了一個工作版本,其中包含消息傳遞和所有內容,均在一個組件中,但我需要將它們作為單獨的組件。

我仍然是初學者。

 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); }); 

這是狀態而非引用的一個很好的用例,就我個人而言,我避免使用引用,狀態更具響應性。

單擊會議室后,您可以將setState與會議室或正在唱歌,然后可以將此ID作為道具傳遞給聊天組件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM