2016-12-23 617 views
0

我在尝试更新现有的React select(下拉列表)以包含当前在服务器上的所有用户。我有一个服务器上所有用户的数组,我只是无法让我的下拉列表更新数组。如何动态创建ReactJs下拉菜单的选项?

这里是我的代码:

class UserList extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 
    this.state = {value: ''}; 
 
    this.handleChange = this.handleChange.bind(this); 
 
    this.handleSubmit = this.handleSubmit.bind(this); 
 
    } 
 

 
    handleChange(event) { 
 
    socket.emit('join', {room: this.state.value}); 
 
    this.setState({value: event.target.value}); 
 
    alert('People on server: ' + this.state.value); 
 
    event.preventDefault(); 
 
    } 
 

 
    handleSubmit(event) { 
 
    //not really using this 
 
    event.preventDefault(); 
 
    } 
 
    
 

 
    render() { 
 
    return (
 
     <form onChange={this.handleChange}> 
 
     <label> 
 
      Pick your favorite La Croix flavor: 
 
      <select id="userlist" value={this.state.value} onChange={this.handleChange}> 
 
      {this.props.list.map((name) => <option>{name}</option>)} 
 
      </select> 
 
     </label> 
 
     
 
     </form> 
 
    ); 
 
    } 
 
} 
 

 

 
class Login extends React.Component { 
 
    render() { 
 
    return (
 
     <div className="login"> 
 
      <NameForm /> 
 
      <UserList list={users} /> 
 
      <Chat /> 
 
      <ChatInput /> 
 
     </div> 
 
    ); 
 
    } 
 
}

我很新的反应,我不明白如何让元素通过外部请求更新(在这种情况下,服务器)。现在,我的JavaScript将服务器上的人员列表存储在由服务器更新的名为“users”的数组中。我希望下拉列表可以在数组进行更新时更新。

编辑:

这里是填充用户数组的代码:

socket.on('update_list', function(msg) { 
 
    users.push(msg.data); 
 
});

的用户阵列的服务器调用 'update_list' 后肯定是更新。在用户被调用之后,我已经打印了这些值,并且当新用户登录时,用户会相应地进行更新。

+1

所以,你将用户数组传递给UserList。你可以发布填充'users'数组的代码吗?听起来就像你对它使用'setState'不正确。 –

+0

我编辑了我的原始文章,以显示填充'users'数组的javascript的一点点。我遗漏了我声明'用户'的地方,但它对react元素和套接字函数都是全局访问的。你能否详细说明使用'setState'。我不确定如何正确使用它。 – monker

回答

0

问题是你不能只是添加到一个正常的变量,并期望React神奇知道重新呈现虚拟html,即users.push(...)

setState是你想要的功能。在你调用这个函数后,它会更新它自己的渲染方法,并且它是子组件。

您的api调用需要位于组件中。

例如,每当用户改变时,它将更新渲染方法,因为我们使用setState,它将重新呈现新用户。

选择没有值属性。你想要这个选项,并可能希望用户成为一个对象。我更新了代码。

这只是一个例子。

class UserList extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {value: ''}; 
    this.handleChange = this.handleChange.bind(this); 
    this.handleSubmit = this.handleSubmit.bind(this); 
    } 

    handleChange(event) { 
    socket.emit('join', {room: this.state.value}); 
    this.setState({value: event.target.value}); 
    alert('People on server: ' + this.state.value); 
    event.preventDefault(); 
    } 

    handleSubmit(event) { 
    //not really using this 
    event.preventDefault(); 
    } 


    render() { 
    return (
     <form onChange={this.handleChange}> 
     <label> 
      Pick your favorite La Croix flavor: 
      <select id="userlist" onChange={this.handleChange}> 
      {this.props.users.map(user => <option value={user.value}>{user.name}</option>)} 
      </select> 
     </label> 

     </form> 
    ); 
    } 
} 

class Parent extends React.Component { 
    constructor(props) { 
    super(props); 

    this.getUsers = this.getUsers.bind(this); 

    this.state = { 
     users: {} 
    } 
    } 
    componentDidMount() { 
    this.getUsers(); 
    } 

    getUsers() { 
     socket.on('update_list', function(msg) { 
      this.setState({users: msg.data}); 
     }.bind(this)); 
    } 
    render() { 
    return (
     <UserList users={this.state.users}/> 
    ); 
    } 
}