如何正确地将数组传递给状态

时间:2018-12-23 15:20:34

标签: reactjs

我对反应setState有疑问,我想传递到状态disciplinesArray 在功能setArray()中。排序进行得很好,但数组没有过滤。在setArray()的控制台日志中,我看到已过滤和排序数组,但状态仅是排序。

在我添加setToggle()setInitialArray()

之前,所有方法都有效
constructor(props) {
    super(props)
    this.state = {
        filterType: 'all',
        sortType: 'alphabetical',
        arrayOfDisciplines: this.setInitialArray()
    }
}
componentDidUpdate(prevState) {
    console.log(this.state)
    if (prevState===this.state) {
        this.setState({
            disciplinesArray: this.setArray()

        })
    }
}
setInitialArray() {
    let disciplinesArray = this.props.disciplines
    disciplinesArray = disciplinesArray.map((discipline) => {
        return discipline = {
            ...discipline,
            score: disciplineScore(this.props.athlete.skillset, discipline.requirements),
            isHidden: false
        }
    })
    return disciplinesArray
}
setArray() {
    let disciplinesArray = this.state.arrayOfDisciplines
    switch (this.state.sortType) {
        case 'alphabetical':
            disciplinesArray = disciplinesArray.sort((a, b) => {
                return a.name.localeCompare(b.name)
            })
            break
        case 'score':
            disciplinesArray = disciplinesArray.sort((a, b) => {
                return a.score - b.score
            })
            break
        default:


    }
    switch (this.state.filterType) {
        case 'team':
            console.log('team')
            disciplinesArray = disciplinesArray.filter((discipline) => {
                return discipline.isIndividual === false
            })
            break
        case 'individual':
            console.log('team')
            disciplinesArray = disciplinesArray.filter((discipline) => {
                return discipline.isIndividual === true
            })
            break
        default:
    }
    return disciplinesArray
}
setToggle(disciplineName, props) {
    let disciplinesArray = this.state.arrayOfDisciplined
    disciplinesArray.find((discipline) => {
        return discipline.name === disciplineName
    }).isHidden = !disciplinesArray.find((discipline) => {
        return discipline.name === disciplineName
    }).isHidden
    console.log(disciplineArray)
    return disciplinesArray

}
setSortType(e) {
    this.setState({
        sortType: e.target.value
    })
}
setFilterType(e) {
    this.setState({
        filterType: e.target.value
    })
}
}

我希望过滤和排序后的数组处于状态

1 个答案:

答案 0 :(得分:0)

恐怕您的代码中充满了小错误。排序有效的事实实际上是另一个错误的随机结果。考虑您的初始状态:

this.state = {
    filterType: 'all',
    sortType: 'alphabetical',
    arrayOfDisciplines: this.setInitialArray()
}

将初始数组存储到this.state.arrayOfDisciplines中。

但是,更改值时:

this.setState({
   disciplinesArray: this.setArray()
})

您正在将其存储到this.state.disciplinesArray

那行不通,它们应该相同。

它起作用的事实是由另一个错误引起的:

let disciplinesArray = this.state.arrayOfDisciplines
switch (this.state.sortType) {
    case 'alphabetical':
        disciplinesArray = disciplinesArray.sort((a, b) => {
            return a.name.localeCompare(b.name)
        })
        break

这实际上是引用对您状态下的数组的引用,在state中对该数组进行排序,并存储在局部变量中。请注意,Array.sort对数组进行原位排序,因此通常应在其前加上slice

 disciplinesArray = disciplinesArray.slice().sort((a, b) => {
     return a.name.localeCompare(b.name)
 })

总而言之:您的错误是setState中一个错误的属性名称,并且您直接在state中更改了值。

setToggle函数中也可以看到相同的问题,该函数还直接修改状态。它应该看起来像这样:

return this.state.arrayOfDisciplined
   // always create a new array, don't just update a value inside the array
   .map(discipline => {
       if (discipline.name !== disciplineName) {
          return discipline;
       } 

       // always create a new immutable object, don't mutate the old state
       return {
           ...discipline,
           isHidden: !discipline.isHidden
       };
   });