首页 > 解决方案 > React onClick 方法在第一次选择时给出 undefined 和传递的值不一样?

问题描述

我试图创建这个用户列表,单击它们应该打开相应的用户消息,但是在第一次单击时传递了一个“未定义”值,然后

我已经尝试搜索问题,也尝试了 github 的相关代码,但没有任何可靠的东西出现

我有以下代码:-

//code where the selection takes place 
 setselectRoomId(id)
   {
       this.toggleMessageContainer(false,true);
       this.setState({selectedRoomid:id});
   }
//code where the effect on changing selection should take place 
loadConversation(id)
    {
        this.setState({isLoading:true,disableTextArea:true})
        let room=(id) ? id : this.props.selectedRoomid
        //let data={room:selectedRoomId}
        axios('/chat/messages/'+room).then(res=>{
            this.setState({messages:res.data.messages,isLoading:false,disableTextArea:false});
             console.log(res);
        }).catch(err=>{
            console.log(err);
        });
    }
// front end code where click event occurs
    render()
    {
        let {showRoomPanel,onlinerooms}=this.props;
        let {activeRoom,isLoading,currentUser}=this.state;
        let roomStyle=(showRoomPanel==false) ?"rooms-panel hide-div":"rooms-panel"
        return(
            <div className={roomStyle}>
              { (isLoading===true) ? <Spinner></Spinner>:
                 this.state.rooms.map((room)=>{
                     return <Roominfo
                        key={room.room}
                        userInfo={currentUser}
                        activeRoomId={activeRoom}
                        onlinerooms={onlinerooms}
                        senderName={room.senderName}
                        senderId={room.senderId}
                        setSelectedRoomId={this.setSelectedRoomid.bind(this,room.room)}/>
                 })

              }


   // the onclick event
  const RoomInfo=({senderName,roomId,senderId,setSelectedRoomId,activeRoomId})=>{
       const allConstants= new Constants();
       return(
           <div className={(activeRoomId==roomId) ? "room-info active-room":"room-info"} onClick={setSelectedRoomId}>
               <div className='room'>
                  <p> {senderName}</p>
               </div>
           </div>
       );
    }
                    </div>
                );
            }

// 房间面板类

import React,{Component} from 'react';
import axios from 'axios';
import Roominfo from './Roominfo';
import {Spinner} from 'reactstrap';
import Constants from '../Constants';
import decode from 'jwt-decode';
import '../Styles/RoomPanel.css';
class Roompanel extends Component{
    state={
        rooms:[],
        isLoading:true,
        message:null,
        currentUser:null
    }
    constructor(props)
    {
        super(props);
        this.allConstants=new Constants();        
    }
    componentDidMount()
    {
        this.loadRooms()
    }
    loadRooms()
    {
        //let allConstants=this.allConstants
        const token=decode(localStorage.getItem('token'));
        const rid=token.id;
        this.setState({currentUser:rid});
        const data={rid:rid}
        axios.get('/chat/user/'+rid).then(res=>{
               //console.log(res.data.users);
               this.setState({rooms:res.data.users,isLoading:false});

        }).catch(err=>{
              console.log(err);
              this.setState({isLoading:false,message:'error occured'});
        });
    }
    setSelectedRoomId(id)
    {
        this.props.setselectRoomId(id)
        //console.log(this.props.selectedRoomid)
        this.setState({activeRoom:id});
    }
    render()
    {
        let {showRoomPanel,onlinerooms}=this.props;
        let {activeRoom,isLoading,currentUser}=this.state;
        let roomStyle=(showRoomPanel==false) ?"rooms-panel hide-div":"rooms-panel"
        return(
            <div className={roomStyle}>
              { (isLoading===true) ? <Spinner></Spinner>:
                 this.state.rooms.map((room)=>{
                     return <Roominfo
                        key={room.room}
                        userInfo={currentUser}
                        activeRoomId={activeRoom}
                        onlinerooms={onlinerooms}
                        senderName={room.senderName}
                        senderId={room.senderId}
                        setSelectedRoomId={this.setSelectedRoomId.bind(this,room.room)}/>
                 })

              }
            </div>
        );
    }

}
export default Roompanel;

//应该发生效果的消息面板类

import React,{Component} from 'react';
import axios from 'axios';
import Message from './Message';
import WriteMessage from './WriteMessage';
import {Spinner} from 'reactstrap';
import '../Styles/MessagePanel.css';
class MessagePanel extends Component{
    state={
        messages:[],
        isLoading:false,
        disableTextArea:true

    }
    constructor(props)
    {
        super(props);
         this.onLineRoom=this.onLineRoom.bind(this);
    }
    componentDidMount()
    {
        this.scrollToBottoom()
    }
    componentWillUpdate()
    {
        this.scrollToBottoom()
    }
    scrollToBottoom()
    {
        this.messageEnd.scrollIntoView({behaviour:'smooth'});
    }
    componentWillReceiveProps(nextProps)
    {

            this.loadConversation(nextProps.selectedRoomId)
            console.log(this.props.selectedRoomid)

    }
    loadConversation(id)
    {
        this.setState({isLoading:true,disableTextArea:true})
        let room=(id) ? id : this.props.selectedRoomid
        //let data={room:selectedRoomId}
        axios('/chat/messages/'+room).then(res=>{
            this.setState({messages:res.data.messages,isLoading:false,disableTextArea:false});
             console.log(res);
        }).catch(err=>{
            console.log(err);
        });
    }
    onNewMessageArrival(data)
    {
        let newMessages=[...this.state.messages]
        if(data.room==this.props.selectedRoomId)
        {
            this.setState((prevState,props)=>({
                messages:[...this.state.messages,{...data}]
            }));
        }
      this.props.fillRoomInfoFromSocket(data)
    }
    onLineRoom(roomsOnline)
    {
        this.props.notifyOnlineRooms(roomsOnline);
    }
    render()
    {
        let {messages,isLoading,disableTextArea}=this.state
        let{selectedRoomId,showMessagePanel}=this.props
        let messageStyle=(showMessagePanel==true) ? "message-panel":"message-panel hide-div"
        return(
            <div className={messageStyle}>
                <div className='show-messages'>
                    {
                        (isLoading==true) ? <Spinner></Spinner> :
                         messages.map(message=>{
                             return <Message key={message.id} Message={message.Message} senderId={message.senderId} recieverId={message.recieverId} />
                         })
                }
                     <div style={{ float: "left", clear: "both" }} ref={(el) => { this.messageEnd = el; }}></div>   
                </div>
                <WriteMessage
                   isDisabled={disableTextArea}
                  // userInfo={userInfo}
                   selectedRoomId={selectedRoomId}
                   onLineRoom={this.onLineRoom}
                   onNewMessageArrival={this.onNewMessageArrival.bind(this)}/>
            </div>
        );
    }
}
export default MessagePanel;

// 两个组件相遇的主类

import React,{Component} from 'react';
import Constants from './Constants';
import Roompanel from './Rooms/Roompanel';
import MessagePanel from './Message/MessagePanel'; 
class Messagecontainer extends Component{
   state={
       showMessagePanel:true,
       showRoomPanel:true,
       onlinerooms:[]
   }
   constructor(props)
   {
       super(props);
       this.setselectRoomId=this.setselectRoomId.bind(this);
       this.fillRoominfointoSocket=this.fillRoominfointoSocket.bind(this);
       this.notifyOnlinerooms=this.notifyOnlinerooms.bind(this);

   }
   fillRoominfointoSocket(message)
   {
       this.setState({newMessageFromSocket:message});
   }
   componentDidMount()
   {
       this.toggleMessageContainer(true,false);
   }
   toggleMessageContainer(showRoomPanel,showMessagePanel)
   {
       if(window.innerWidth<500)
       {
        this.setState({showRoomPanel,showMessagePanel});
       }
   }
   setselectRoomId(id)
   {
       this.setState({selectedRoomid:id});
       this.toggleMessageContainer(false,true);

   }
   notifyOnlinerooms(rooms)
   {
       this.setState({onlinerooms:rooms});
   }
   render()
   {
    let{showMessagePanel,showRoomPanel,selectedRoomid,newMessageFromSocket,onlinerooms}=this.state;
    if(window.innerWidth<500)
    {
        showMessagePanel=false;
        showRoomPanel=true;
    }
       return(
           <div className='content'>
            <Roompanel 
            showRoomPanel={showRoomPanel}
            onlinerooms={onlinerooms}
            setselectRoomId={this.setselectRoomId}
            selectedRoomid={this.state.selectedRoomid}
            newMessageFromSocket={newMessageFromSocket}/>
            <MessagePanel
            showMessagePanel={showMessagePanel}
            selectedRoomid={selectedRoomid}
            fillRoominfointoSocket={this.fillRoominfointoSocket}
            notifyOnlinerooms={this.notifyOnlinerooms}/>
           </div>
       );
   }
}
export default Messagecontainer;

谁能解释我如何调试这个问题,因为它在我的代码中产生了一些问题?

标签: javascriptreactjsmern

解决方案


setSelectedRoomId(id)不接收id变量,而是接收您必须访问的点击事件e.target.value

此外,如果要从 click 事件中检索 value 属性,还必须为单击的元素设置 value 属性

首先添加value={roomId}到可点击 div 的 props:

<div value={roomId} onClick={setSelectedRoomId} className={(activeRoomId==roomId) ? "room-info active-room":"room-info"}>

然后更改您的 setSelectedRoomId 方法以解构单击事件:

setselectRoomId(e){
       const id = e.target.value
       this.toggleMessageContainer(false,true);
       this.setState({selectedRoomid:id});
   }

推荐阅读