【问题标题】:React dropdown / select not updating state反应下拉/选择不更新状态
【发布时间】:2020-02-01 10:19:25
【问题描述】:

如果我尝试更新的状态在用户数组之外,则更新状态有效。但是由于我有多个用户,所以我需要将状态放在对象内部并无论如何都要更新

我不断收到错误TypeError: Cannot read property 'name' of undefined

我曾想过在循环内设置状态,但有人告诉我这是个坏主意。

所以[e.target.name]: e.target.value 是我能找到的唯一下拉代码。

我尝试为每个用户传递 id,但不知道如何使用它来更改状态或放置什么条件。

import React, { Component } from 'react'
export default class App extends Component {

  state = {
    users: [
      {
        id: uuid(),
        firstName: 'John',
        lastName: 'Doe',
        favColor: 'None'
      },
      {
        id: uuid(),
        firstName: 'Jane',
        lastName: 'Doe',
        favColor: 'None'
      }
    ]
  }

  handleChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value
    })
  }

  render() {

    return (
      <div>
        {this.state.users.map((user) => {

          return <div key={user.id}>

            <h1>{user.firstName}</h1>
            <h1>{user.lastName}</h1>

            <form>
              <select 
                  name="favColor" 
                  value={user.favColor} 
                  onChange={() => this.handleChange(user.id)}
              >
                <option value="None" disabled>None</option>
                <option value="Blue">Blue</option>
                <option value="Red">Red</option>
                <option value="Green">Green</option>
              </select>
            </form>

            <h1>Fav Color: {user.favColor}</h1>
            <hr />
          </div>
        })}
      </div>
    )
  }

}

我希望下拉菜单为每个用户单独更改状态

【问题讨论】:

  • 像这样改变 onChange :onChange={(e) =&gt; this.handleChange(e)
  • 你想要的状态结构是什么?加上e.target.name 是选择的名称。
  • @rapSherlock 似乎已经消除了错误并在 React 工具中显示状态正在更新,但在 UI 中没有显示任何更改
  • 因为你的用户状态是数组

标签: javascript reactjs select state dropdown


【解决方案1】:

您以错误的方式更新状态;

您所在的州:

users: [
    { id: 1, ... },
    { id: 1, ... }
]

您的更新/意图:

users: [
    { id: 1, ... },
    { id: 1, ... }
]
favColor: color // intention, because you don’t pass event

要以正确的方式更新,您需要:

  • 将所选下拉列表的事件和 currentId 传递给 handleChange。否则你无法知道当前用户。此外,在您的示例中,您没有传递事件,因此您无法检索下拉列表的信息。导致名称未定义的错误。
  • 检查用户 id 何时与下拉列表的 id 匹配并更改值。

这个例子应该适合你。

https://codesandbox.io/s/small-sea-mw08n

【讨论】:

  • 很高兴我能帮上忙,我做了一些小修改,让您和其他人更清楚。
  • 我在几个小时后重新访问了那个codeandbox,现在它是一个完全不同的链接。你那边也是这样吗?
  • 对不起,我搞砸了。我将沙箱重新用于其他用途。我为此主题重新创建了一个带有新 ID 的沙箱。请检查一下好吗?
【解决方案2】:

您的handleChange 方法不接受正确的参数。 如果您希望更新数组中的一个用户项,您需要创建一个新的更新后的数组副本并保存回状态

handleChange = (e,id) => {
const updatedUser = {...this.state.users.find(x=>x.id ===id), favColor: e.target.value}
 this.setState({
    users:  [...this.state.users.filter(x==>x.id!==id),updatedUser]
    })
}

...
onChange={(e) => this.handleChange(e,user.id)}

为了简化状态突变,我建议您查看Immer

正如@JosephD 正确指出的那样,这不会维持秩序,因此您需要执行this.state.users.map(u =&gt; u.id === id ? { ...u, favColor: e.target.value } : u) 之类的操作

这是一个基于您的代码的代码框: https://codesandbox.io/s/loving-cohen-do56l?fontsize=14

【讨论】:

  • 如果我执行上述操作,它会删除我的 firstNames 和 lastNames onChange 并使 Fav Color: 从“无”(初始状态)变为空
  • 它是否通过 id 正确找到了用户? updatedUser 现在的形状是什么样的?你检查id的值了吗?
  • 好的,所以如果我 console.log(id) onchange 它只第一次显示一个 id 而所有其他更改都显示未定义
  • 如果我在更改之前控制状态,它会显示两个对象,但更改后会显示 (2) [false, true] 然后 (2) [false, false]
  • 也感谢 Damian 坚持了一个小时并修复了我的代码,非常感谢
【解决方案3】:
  <select 
     name="favColor" 
     value={this.state.favColor} 
     onChange={(e) => this.handleChange(e)}>  // first Change

 handleChange = (e) => {
    this.setState({
     favColor: e.target.value 
    })
  } // Second Change

这对你有用

【讨论】:

  • 似乎已经消除了错误并在 React 工具中显示状态正在更新,但在 UI 中没有显示任何更改
  • yaa,因为默认值是user.favColor,我编辑了答案,试试这个对你有用
  • value={this.state.favColor} 是错误的,我在循环中显示用户,所以它需要 value={user.favColor}
猜你喜欢
  • 2016-03-08
  • 2019-02-19
  • 1970-01-01
  • 2021-06-09
  • 1970-01-01
  • 2018-03-28
  • 2019-12-13
  • 1970-01-01
相关资源
最近更新 更多