当我从状态中删除项目时,组件不会重新渲染,但是当我添加项目时它会重新渲染

Cla*_*ude 2 reactjs

我有一个 Liked 方法,它根据返回值检查数组中的现有项目,组件 Recipe_serving 有条件地显示。我在这里注意到的是,当我将一个项目添加到数组(likedList)子组件重新渲染并检查条件时,但是当我删除项目时,即使使用了 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>
    )
}
Run Code Online (Sandbox Code Playgroud)

Cer*_*rus 5

关键是 React 检查 props/state 的变化只是浅层的——任何子对象(和数组,因为它们是对象)都是通过引用而不是值来检查的。

当您使用扩展运算符添加项目时,您实际上是通过克隆当前数组来创建一个全新的数组,因此 React 会注意到这一点并触发重新渲染。当你删除的项目,但是,这是不同的,因为splice作品在原地,并引用数组保持不变。

如何解决这个问题:

  1. 用于在删除项目之前slice克隆。prevState.likedListsplice

  2. 使用filter创建一个新的阵列,除此之外的所有现有元素。

  3. 使用扩展运算符,例如:

return {
    likedList: [...prevState.likedList.slice(0, index), ...prevState.likedList.slice(index + 1)]
}
Run Code Online (Sandbox Code Playgroud)
  1. 最后,您可以forceUpdate()在设置状态后仅使用组件(不推荐,因为它破坏了语义,但可能)。