[英]How do I remove and add Array elements within an Object used for State?
我试图创建此功能可用于this.state.user.id添加到this.state.players.team1同时通过其他阵列this.state.players内检查,以去除this.state.user。 id(如果存在)。
这里是一些上下文:
// function is used for onClick()
// this.state.players = {
// team1: [1, 2],
// team2: [5, 7]
// }
// this.state.user.id = 7
// (team) parameter is passed with "team1" or "team2" depending on situation
下面是我尝试编写的函数。 有没有更好的办法写出来? this.setState异步执行,这破坏了我的功能。
onJoinTeam(team) {
// remove player id from any id
this.setState({
players:
Object.entries(this.state.players).map(key => {
return key[1].filter(player => player !== this.state.user.id)
})
})
// add this.state.user.id to this.state.players
this.setState({
players: {
...this.state.players,
[team]: [ ...this.state.players[team], this.state.user.id ],
}
})
}
阅读完您所有的想法后,我想出了一个解决方案。 这是我现在所拥有的:
onJoinTeam(team) {
const { players } = this.state;
const newTeams = {}
Object.entries(players).map(([key, value]) => {
const filteredTeamObj = {
[key]: value.filter(player => player !== this.state.user.id) }
return Object.assign(newTeams, filteredTeamObj)
})
this.setState({
players: {
...newTeams,
[team]: [ ...this.state.players[team], this.state.user.id ],
}
})
}
再次感谢大家
我会尝试像
const { players } = this.state;
for (const team in players) {
const teamPlayers = players[team];
const playerIndex = teamPlayers.findIndex(tp => tp === userId);
if (playerIndex !== -1) {
teamPlayers.splice(playerIndex, 1);
break;
}
}
players[newTeam].push(userId);
this.setState({ players });
可以在此片段中看到实际效果
class App extends React.Component { state = { players: { team1: [1, 2, 3], team2: [4, 5, 6], }, }; render() { return ( <div> <pre>{JSON.stringify(this.state, null, 4)}</pre> <form onSubmit={(e) => this.onJoinTeam(e)}> <label>User ID</label> <input name="userId" type="number" min="1" max="6" step="1" /> <br /> <label>New Team</label> <select name="newTeam"> <option value="team1">Team 1</option> <option value="team2">Team 2</option> </select> <br /> <button type="submit">Move player</button> </form> </div> ); } onJoinTeam(e) { e.preventDefault(); const newTeam = e.currentTarget.newTeam.value; const userId = parseInt(e.currentTarget.userId.value, 10); const { players } = this.state; for (const team in players) { const teamPlayers = players[team]; const playerIndex = teamPlayers.findIndex(tp => tp === userId); if (playerIndex !== -1) { teamPlayers.splice(playerIndex, 1); break; } } players[newTeam].push(userId); this.setState({ players }); } } ReactDOM.render(<App />, document.getElementById('root'));
<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="root"></div>
这是另一种解决方案,不是那么简单,也许不是那么可读,但是它可以工作:)使用Object.entries
我们创建了一个地图。 在执行此操作时,我们正在检查team
是否等于我们的key
。 如果是的话,我们我们添加id
到我们的key
,如果不是我们筛选出的id
。 最后一步是使用带有reduce
数组创建对象。
class App extends React.Component { state = { players: { team1: [1, 2], team2: [5, 7], team3: [9, 6, 7], }, id: 7, } componentDidMount() { this.change( "team1" ); } change = team => { const { players, id } = this.state; const newPlayers = Object.entries(players).map(([key,value]) => team === key ? { [key] : [ ...value, id ] } : { [key]: value.filter(player => player !== id) } ).reduce( ( obj, item) => ({ ...obj, ...item, }) ); this.setState({players: newPlayers}) } render() { console.log( this.state.players ); return ( <div> Look the console to see the old and new value of the players. </div> ); } } ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.