【问题标题】:How to pass an object value in a form's select field onChange (using React, without Redux)如何在表单的选择字段 onChange 中传递对象值(使用 React,不使用 Redux)
【发布时间】:2018-01-08 22:51:36
【问题描述】:

我目前正在开发一个带有简单表单的 react 组件(没有 redux,只使用 react-bootstrap 进行样式设置)

我正在以下列形式从数据库中提取数据:

[
  {
    "id":"123",
    "name":"Amy Pond",
    "age":"22",
    "reputation":22000
  },
  {
    "id":"124",
    "name":"Clara Oswald",
    "age":"24",
    "reputation":35000
 }
 ...
]

并将其放入对象中:

let userlist = [];
userlist = addUsers(this.state.users);

我使用map根据这个数据填充了一个下拉列表,并且可以正确地将用户的状态设置为从下拉列表中选择的:

<FormControl
   id = "user"
   componentClass="select"
   onChange={this.handleChange}
>
   {userlist.map((r , i) =>
     <option
       key={i}
       value={r.name}>
       {r.name}
     </option>
  )}
</FormControl>

使用handleChange()

handleChange(event) {
  this.setState({
    value: event.target.value,
    // reputation: ???? // here's where I'm running into issues
    // age: ???????  // and here
});

我的问题是,我需要用户在 handleChange 函数中的年龄和声誉来相应地设置他们的状态。我试过只传递r 而不是r.name,但我得到了[object Object]

console.log ("Handle Change Value: " + event.target.value);

如果我尝试event.target.value.name,我会返回undefined

到目前为止,唯一有效的方法是使用 JSON.stringify,但我觉得这不是正确的方法。我还考虑过在获得名称后就搜索对象,但是如果有很多对象,我认为效率会非常低吗?我也不知道该怎么做。

谁能帮我找到一种方法来传递这两个额外的值,以便我可以设置状态?地图甚至是创建选项的最佳方式吗?老实说,我觉得这是一件如此简单的事情,但我还是新手,我已经为此苦苦挣扎太久了!

任何想法/更改/ cmets / 方法来使它变得更好,将不胜感激!我意识到也许使用像 redux-form 这样的东西会使这更容易,但我希望现在有一种简单的方法可以做到这一点。

编辑: onChange 应该设置为onChange = {this.handleChange},只是粘贴了我尝试进行故障排除的错误代码。我在构造函数中绑定了这个:

constructor(props) {
  super(props);
  ...
  this.handleChange = this.handleChange.bind(this);
}

【问题讨论】:

  • 我有一个关于这个相同结构的小问题。当我像这样使用它时:&lt;Animal name = {animal.name} age = {animal.age} clicked = {this.removeAnimal.bind(this, i)} setName = {this.setAnimalName.bind(this, i)} index = {i}/&gt; 这整个东西都在 js map 方法调用的参数箭头函数中。在setAnimalName 方法中,我收到第二个对象作为事件对象,这是否可能?如果您有任何想法,请帮助我

标签: javascript reactjs react-bootstrap


【解决方案1】:

使用用户 ID 作为每个 option 中的值,然后在 handleChange 中找到您的 userlist 中的用户以访问该用户的所有属性:

<FormControl
   id = "user"
   componentClass="select"
   onChange={this.handleChange.bind(this)}
>
   {userlist.map((r , i) =>
     <option
       key={i}
       value={r.id}>
       {r.name}
     </option>
  )}
</FormControl>

handleChange(event) {
  const userId = event.target.value;
  const user = userlist.find(u => u.id === userId);
  this.setState({
    value: user
  });
}

此外,您传递onChange 属性的方式可能会导致问题。如果不查看所有代码,很难判断,但请确保传递对 handleChange 函数的引用(请参阅我的回答中的上文),而不是在此处直接调用它(如您的问题:onChange={this.handleChange()},除非您的this.handleChange函数返回一个函数)。

【讨论】:

  • 这成功了!谢谢:) 后续问题:我在componentWillMount() 中进行axios 调用,并设置this.setState({ users: response.data, usersArray:addUsers(response.data) }); 之类的状态我需要使用addUsers() 处理数据以仅获取我想要的数据。我目前正在render() 中执行userlist = addUsers(this.state.users);,因为似乎直到那时才收到原始数据。在我的handleChange中,我无法访问用户列表,所以必须使用状态列表const user = this.state.userArray.find(u =&gt; u.id === userId)你知道我怎样才能做得更好吗?
  • componentWillMount() 中进行axios 调用是对的。当您收到响应时,我会在您将数据添加到组件的状态之前转换您的数据。一旦它处于状态,您就可以在render 方法(以显示下拉选项)和handleChange 函数(以通过id 查找所选用户)中访问它。
  • 我有一个关于这个相同结构的小问题。当我像这样使用它时:&lt;Animal name = {animal.name} age = {animal.age} clicked = {this.removeAnimal.bind(this, i)} setName = {this.setAnimalName.bind(this, i)} index = {i}/&gt; 这整个东西都在 js map 方法调用的参数箭头函数中。在setAnimalName 方法中,我收到第二个对象作为事件对象,这是否可能?如果您有任何想法,请帮助我
【解决方案2】:

您设置事件侦听器的方式可能有问题,设置onChange={this.handleChange()} 会导致侦听器立即触发。使用onChange={this.handleChange} 可以正确设置监听器。

<FormControl
   id = "user"
   componentClass="select"
   onChange={this.handleChange}>
   {userlist.map((r , i) =>
     <option
       key={i}
       value={r.name}>
       {r.name}
     </option>
  )}
</FormControl>

有关活动的更多信息,请参阅here

然后您可以在事件处理程序中使用find() 来定位用户:

handleChange(event) {
  let user = users.find(u => u.name === event.user.name);
  this.setState({user: user});
}

【讨论】:

  • 嗯,当我用正确的{this.handleChange} 尝试这个时,我遇到了以下错误:TypeError: Cannot read property 'find' of undefined 有什么想法吗?跨度>
【解决方案3】:

您可以使用选项标签属性和 json 来编码/解码,如下所示:

<FormControl
        id="user"
        componentClass="select"
        onChange={this.handleChange.bind(this)}
    >
        {userlist.map((r, i) =>
            <option
                key={i}
                value={r.id}>
                {r.name}
                data={JSON.stringify(r)}
            </option>
        )}
    </FormControl>;

    handleChange(event)
    {
        if (e.target.options && e.target.selectedIndex) {
            const user = e.target.options[e.target.selectedIndex].getAttribute('data');
            this.setState({
                value: user
            });
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-01
    • 1970-01-01
    • 2022-12-21
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多