Javascript 在数组中切换项
我想切换数组中对象的属性。数组如下所示。这在react组件中使用,当用户单击按钮时,我想切换赢家Javascript 在数组中切换项,javascript,arrays,reactjs,ecmascript-6,Javascript,Arrays,Reactjs,Ecmascript 6,我想切换数组中对象的属性。数组如下所示。这在react组件中使用,当用户单击按钮时,我想切换赢家 const initialFixtures = [{ teams: { home: 'Liverpool', away: 'Manchester Utd' }, winner: 'Liverpool' }, { teams: { home: 'Chelsea', away: 'Fulham' },
const initialFixtures = [{
teams: {
home: 'Liverpool',
away: 'Manchester Utd'
},
winner: 'Liverpool'
},
{
teams: {
home: 'Chelsea',
away: 'Fulham'
},
winner: 'Fulham'
}, ,
{
teams: {
home: 'Arsenal',
away: 'Tottenham'
},
winner: 'Arsenal'
}
];
我的react代码如下所示
function Parent = () => {
const [fixtures, setUpdateFixtures] = useState(initialFixtures)
const toggleWinner = (index) => {
const updatedFixtures = fixtures.map((fixture, i) => {
if (i === index) {
return {
...fixture,
winner: fixture.winner === home ? away : home,
};
} else {
return fixture;
}
})
setUpdateFixtures(updatedFixtures);
}
return <Fixtures fixtures={fixtures} toggleWinner={toggleWinner} />;
}
function Fixtures = ({ fixtures, toggleWinner }) => {
fixtures.map((fixture, index) => (
<div>
<p>{fixture.winner} </p>
<button onClick = {() => toggleWinner(index)}> Change Winner</button>
</div>
))
}
代码可以工作,但感觉有点太多了。我相信有一种更好、更简洁的方法可以做到这一点。有人能提供建议吗?出于体系结构原因,我确实需要从Fixture组件的父级传入Fixture。您可以使用immer之类的库轻松更新嵌套状态
const toggleWinner = (index) => {
let updatedFixtures = [...fixtures].splice(index, 1, {...fixtures[index],
winner: fixtures[index].winner === fixtures[index].teams.home
? fixtures[index].teams.away : fixtures[index].teams.home})
setUpdateFixtures(updatedFixtures);
}
常量initialFixtures=[{
小组:{
主场:“利物浦”,
客场:“曼联”
},
冠军:“利物浦”
},
{
小组:{
主场:“切尔西”,
客场:“富勒姆”
},
获胜者:“富勒姆”
},
{
小组:{
主场:“阿森纳”,
客场:“托特纳姆”
},
冠军:“阿森纳”
}
];
const newState=imer.defaultinitialFixtures,草稿=>{
草稿[1]。获胜者=某物;
};
console.lognewState;
可以将装置阵列分为三个部分:
从0到索引:fixtures.slice0,index。此部件将原封不动地移动到新阵列
索引中的单个项目。此零件/项目因被更改而被丢弃,并替换了一个新项目
数组的其余部分:fixtures.sliceindex+1
接下来,将它们放入一个新阵列:
const newFixtures = [
...fixtures.slice(0, index), // part 1
{/* new item at 'index' */}, // part 2
...fixtures.slice(index + 1) // part 3
];
要构造新项,请执行以下操作:
使用:
使用:
如果您以这种方式编写代码,这将完成工作
const toggleWinner = index => {
const { winner, teams: { home, away } } = fixtures[index];
fixtures[index].winner = winner === home ? away : home;
setUpdateFixtures([...fixtures]);
};
将新的装置数组设置为状态完全足以触发装置组件上的渲染
我已经为你做了一份工作 如果您愿意使用基于类的方法,您可以尝试以下方法: 创建一个保存团队属性值的类。 在这个类中创建一个布尔属性,比如isHomeWinner。此属性将决定胜利者。 然后创建一个getter属性winner,它将查找this.isHomeWinner并提供必要的值。 这将使您拥有一个干净的切换函数:This.isHomeWinner=!这是我的赢家。 您还可以将您的toggleWinner写为: const toggleWinner=索引=>{ const newArr=initialFixtures.slice; newArr[index].切换; 返回newArr; }; 这看起来干净且具有声明性。注意,如果不变性是必要的,那么只需要不变性。如果您对变异值感到满意,只需将fixture.toggle传递到您的react组件。您可能需要绑定上下文,但这也应该起作用 所以它看起来像: 函数Fixtures={Fixtures,toggleWinner}=>{ fixtures.mapixture,索引=> {fixture.winner} fixture.toggle}>更改赢家 //或 //改变胜利者 } 以下是类及其使用的示例: 班级固定装置{ 建筑家,客场,我是赢家{ 这个团队={ 家 离开 }; this.isHomeWinner=isHomeWinner==未定义?true:isHomeWinner; } 赢家{ 返回此.isHomeWinner?this.team.home:this.team.away; } 拨动{ this.isHomeWinner=!this.isHomeWinner } } 设initialFixtures=[ 新赛程‘利物浦’、‘曼联’, 新赛程“切尔西”,“富勒姆”,假, 新赛程‘阿森纳’、‘托特纳姆’, ]; const toggleWinner=索引=>{ const newArr=initialFixtures.slice; newArr[index].切换; 返回newArr; }; initialFixtures.forEachfixture=>console.logfixture.winner 控制台日志'----------' initialFixtures=切换Winner1; initialFixtures.forEachfixture=>console.logfixture.winner initialFixtures=切换Winner2; 控制台日志'----------'
initialFixtures.forEachfixture=>console.logfixture.winnerWhere的changeWinner函数?在何处声明了home和away变量?代码可以工作,但感觉有点太多了。代码审查请求在这里是离题的。看看这个快速问题。这是如何实现的:函数父项==>{正在工作??它是一个在应用程序中呈现的功能组件。如果你是这样问的,它正在使用挂钩?感谢你花时间回答,但它并不真正符合我想要做的。这将变异数组,不会吗?它只会变异updatedFixtures数组。因为这不是状态的一部分,你可以如何变异它如果您关心的是const声明,那么const声明会创建一个对值的只读引用。这并不意味着它所持有的值是不可变的,只是变量标识符不能被重新分配。
const newFixture = {
...oldFixture,
winner: /* new value */
};
const newFixture = Object.assign({}, oldFixture, {
winner: /* new value */
});
const toggleWinner = index => {
const { winner, teams: { home, away } } = fixtures[index];
fixtures[index].winner = winner === home ? away : home;
setUpdateFixtures([...fixtures]);
};