React JS 在状态中存储一组 id

React JS Storing an array of ids in state

我有一个名为 friends 的道具,它被列为复选框(默认:未选中)。

示例输出:

o 鲍勃·史密斯

o 汤姆·布朗

如何保存所有选中名称的 ID?

例如两者都是 ticked/selected -> ids 1 和 2 被存储。

这是我目前拥有的:

class SelectFriends extends Component {
  constructor(props) {
  super(props)
  this.state = {
    SelectedFriendsIds: [],
  }
}

render() {
  const { SelectedFriendsIds } = this.state
  const { userId, friends, addFriendsTo } = this.props

return (
    <div>
      <SubHeader title="Add Friends..." />
      <div>
        {friends
          .mapEntries(([friendId, frn]) => [
            friendId,
            <div key={friendId}>
              <input
                  value={friendId}
                  type='checkbox'
               // onChange={ () => console.log("do something")
                  defaultChecked={false} />
              {frn.firstName} {frn.lastName}
            </div>,
          ])
          .toList()}
      </div>
        <div>
          <Button style="blue" name="Done" onClick={() => addFriendsTo(SelectedFriendIds, userId)} />
        </div>
    </div>
  )
 }
}

export default SelectFriends

您可以简单地使用 array.push 在检查时添加 ID array.filter 来检索单个 ID 和 array.slice 删除单个 id.

这是您的代码的稍微简化的版本,其中包含一个新函数 handleChange,每次复选框 checked/unchecked 时都会调用该函数

我们复制状态并提取selectedFriendsIds。如果要将 id 添加到状态 setState,则调用新值的新数组并合并到 selectedFriendsIds。如果未选中复选框,则调用 setState 并使用过滤后的 selectedFriendsIds 副本。

您可能想要 运行 此代码段整页,因为它会在每次更改后将状态记录到控制台以向您显示输出。

class SelectFriends extends React.Component {

  constructor(props) {
    super(props);
    this.state = { selectedFriendsIds: [] }
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    const { checked, value } = e.target;
    let { selectedFriendsIds } = this.state;
    if (checked) {
      selectedFriendsIds = [...selectedFriendsIds, value];
    } else {
      selectedFriendsIds = selectedFriendsIds.filter(el => el !== value);
    }
    this.setState({ selectedFriendsIds }, () => console.log(this.state));
  }


  render() {
  
    const { friends } = this.props;
  
    return (
      <div>
        <h2>Add Friends</h2>
          {friends.map(({ friendId, frn }) => {
            return (
              <div key={friendId}>
                <input value={friendId} type="checkbox" onChange={this.handleChange} />{frn}
              </div>
            );
          })}
      </div>
    )
  }
}

const friends = [
  { friendId: 1, frn: 'Bob' },
  { friendId: 2, frn: 'Davros' },
  { friendId: 3, frn: 'Daisy' }
];

ReactDOM.render(
  <SelectFriends friends={friends} />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>

还有available in a jsfiddle.

代码可以这样修改

  class SelectFriends extends Component {
    constructor(props) {
        super(props)
        this.state = {
            SelectedFriendsIds: {},  //CHANGING INTO OBJ FOR EASIER MANIPULATION
        }
    }

    render() {
        const { SelectedFriendsIds } = this.state
        const { userId, friends, addFriendsTo } = this.props

        return (
            <div>
                <SubHeader title="Add Friends..." />
                <div>
                    {friends
                        .mapEntries(([friendId, frn]) => [
                            friendId,
                            <div key={friendId}>
                                <input
                                    checked={friendId}   //USE CHECKED ALWAYS FOR CHECKBOXES
                                    type='checkbox'
                                    onChange={(e) => {
                                        let x = SelectedFriendsIds;
                                    if (e.target.checked) {
                                        x[friendId] = true;
                                    }
                                    else {
                                        delete x[friendId];
                                    }
                                    this.setState({
                                        SelectedFriendsIds: x
                                    })
                                    }} />
                                {frn.firstName} {frn.lastName}
                            </div>,
                        ])
                        .toList()}
                </div>
                <div>
                    <Button style="blue" name="Done" onClick={() => addFriendsTo(SelectedFriendIds, userId)} />
                </div>
            </div>
        )
    }
}

export default SelectFriends

如果您需要一组选定的朋友,只需使用

Object.keys(this.state.SelectedFriendsIds)

您需要检查该值是否已在您选择的列表中,如果不存在则添加它,否则删除复选框的值 onChange 事件。检查下面的示例代码

class SelectFriends extends Component {
  constructor(props) {
  super(props)
  this.state = {
    SelectedFriendsIds: [],
  }
}

onChange = (val) => {
   const SelectedFriendsIds = [...this.state.SelectedFriendsIds];
   const presentIndex = SelectedFriendsIds.indexOf(val)
   if(presentIndex > 0) {
      SelectedFriendsIds.splice(presentIndex, 1);
   } else {
      SelectedFriendsIds.push(val);
   }
   this.setState({SelectedFriendsIds})

}
render() {
  const { SelectedFriendsIds } = this.state
  const { userId, friends, addFriendsTo } = this.props

return (
    <div>
      <SubHeader title="Add Friends..." />
      <div>
        {friends
          .mapEntries(([friendId, frn]) => [
            friendId,
            <div key={friendId}>
              <input
                  value={friendId}
                  type='checkbox'
                  onChange={ () => this.onChange(friendId)
                  defaultChecked={false} />
              {frn.firstName} {frn.lastName}
            </div>,
          ])
          .toList()}
      </div>
        <div>
          <Button style="blue" name="Done" onClick={() => addFriendsTo(SelectedFriendIds, userId)} />
        </div>
    </div>
  )
 }
}

export default SelectFriends

我想对您的组件设计提出一个小的改进建议,这也解决了如何有效维护所选好友 ID 状态的问题。坦率地说,没有必要维护所选 ID 的状态。相反,请维护一个朋友集合的状态——其中代表一个朋友的每个对象都有 'selected' 属性。这样,您就可以轻松过滤选定的内容并将此信息发送到上层组件。下面是完整解释这一点的代码片段:

import React, { Component } from 'react';
import * as _ from 'lodash';
import PropTypes from 'prop-types';

class FriendsList extends Component {

state = {
    friends: []
}

constructor(props) {

    super(props);

    this.onAdd = this.onAdd.bind(this);

    this.state.friends = [ {id: 1, name: 'John', selected: false}, 
        { id: 2, name: 'Ally', selected: false},
        { id: 3, name: 'Becky', selected: false},
        { id: 4, name: 'Frank', selected: false},
        { id: 5, name: 'Mark', selected: true},
        { id: 6, name: 'Alice', selected: true}
    ];
}

onCheckboxChange(event, n) {
    n.selected = !n.selected;
    this.forceUpdate();
}

onAdd() {
    const selectedFriends = _.filter( this.state.friends, (friend) => {
        return friend.selected === true;
    });
    this.props.onAdd(selectedFriends);
}

render() {
    const { friends } = this.state;
    return (
        <div>
            {friends.map(n => {
                return (
                    <div key={n.id}>
                        {n.name} <input type="checkbox" onChange={(event) => this.onCheckboxChange(event, n)} checked={n.selected}/>
                    </div>
                );
            })}
            <button onClick={this.onAdd}>Add Friends</button>
        </div>
    );
}
}
FriendsList.propTypes = {
  onAdd: PropTypes.func,
};
export default FriendsList;