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>
代码可以这样修改
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;
我有一个名为 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>
代码可以这样修改
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;