我有一个Liked方法,该方法根据返回值有条件地显示组件Recipe_serving来检查数组中的现有项。我在这里注意到的是,当我向数组(likedList)子组件重新渲染中添加一个项目并且条件为check时,但是当我删除项目时,即使使用setState也不发生重新渲染
class App extends Component {
state = {
result:[],
recipe:{},
isActive:"47746",
addToShopping: [],
likedList:[]
}
setActiveId=(id)=>{
this.getRecipe(id)
}
pushToLikeList = () => {
// if id is in likeList then remove
// if id not in likeList then add
if(this.state.likedList.findIndex(el=>el.recipe.recipe_id===this.state.isActive) === -1){
this.setState(prevState => {
return {
likedList: [prevState.recipe, ...prevState.likedList]
}
})
}else{
this.setState(prevState=>{
const index = prevState.likedList.findIndex(el=>el.recipe.recipe_id===prevState.isActive);
prevState.likedList.splice(index,1)
return{
likedList:prevState.likedList
}
})
}
}
Liked=()=>{
return (this.state.likedList.findIndex(el=>el.recipe.recipe_id===this.state.isActive) !== -1)
}
render() {
return (
<div className="App">
<Recipe_serving
isActive={this.state.isActive}
likedList={this.state.likedList}
pushToLikeList={this.pushToLikeList}
Liked={this.Liked}
/>
</div>
);
}
}
const Recipe_serving = (props)=>{
return(
<div>
<button className="recipe__love" onClick={props.pushToLikeList}>
<svg className="header__likes">
<use href={props.Liked?"img/icons.svg#icon-heart":"img/icons.svg#icon-heart-outlined"}></use>
</svg>
</button>
</div>
)
}
答案 0 :(得分:2)
关键是React只能浅层检查道具/状态更改-任何子对象(和数组,因为它们是对象)都是通过引用而不是值来检查的。
使用散布运算符添加项目时,实际上是通过克隆当前数组来创建一个全新的数组,因此React注意到了这一点并触发了重新渲染。但是,当您删除该项时,它就不同了,因为splice
就可以在原位运行(em),并且对数组的引用保持不变。
该如何解决:
使用slice
克隆prevState.likedList
,然后再用splice
删除项目。
使用filter
创建一个包含除一个元素之外的所有现有元素的新数组。
使用传播运算符,例如:
return {
likedList: [...prevState.likedList.slice(0, index), ...prevState.likedList.slice(index + 1)]
}
forceUpdate()
设置组件(不建议这样做,因为它会破坏语义,但可以)。