如何更高效、方便的在React.js中操作State

1,298 阅读3分钟

1、什么是flatten state?

最近在写代码的时候在React的对象数组的State数据感觉不是很方便,所以在在使用了其他方式来解决这个问题。

flatten state目的是就是把数据扁平化,更加方便我们对数据的操作,flatten就是类似于使用HashMap的形式,在JavaScript中我们可以使用Object

2、实际使用

在这里我们以React为例子,在ReactHooks中我们经常对数据进行操作,但是如果操作的是一个对象数组并且该数组非常大这样时很耗时的,代码也很冗余,所以我们可以考虑把数组转化成为flattenState的形式。

exp

const initState = [
  {id: 1, name: 'RMA', champion: 13},
  {id: 2, name: 'ACM', champion: 7},
  {id: 3, name: 'MUN', champion: 4},
  {id: 4, name: 'ARS', champion: 0}
]
const [teams, setTeams] = useState()

对于这样的数据如果我们需要查找某一个数据或者修改某一个数据时对应的时间复杂度为O(n),因为我们每次对数据进行操作都需要循环遍历一次数组。

// 删除一项
const deleteData = (id) => {
    return teams.filter(item => item.id !== id)
}
const newTeams = deleteData(3)
setTeams(newTeams)

// 修改一项
const modifyData = (id, val) => {
    return teams.map(item => {
        if(item.id === id) { // tips:item为引用值可以改变
            item.champion = val
        }
        return item
    })
}
const newData = modifyData(4, 1)
setTeams(newData)

// 查找一项
const findData = (id) => {
    return teams.find(item => item.id === id)
}

在我们熟悉使用数组的一些高阶方法之后操作起来还是比较方便的,但是如果数据量过大每次循环还是很耗时的。有没有更好的方法呢?当然就是使用flattenState(Object)来解决。

3、使用hashMap的形式

上面的数据有一个特点就是每一个数据项都具体有唯一的标识符(id),在上面的例子中我们在查找某一个数据项的时候使用的该唯一标识符。

所以我们可以思考在查找某个特定的数据的时候不需要再通过循环遍历每一项然后使用每一项的id和特定id对比,我希望可以直接访问id就能够访问到其对应的数据不需要再使用循环了,能够做到这样能力就是对象(object)。

所以我们需要将上面的形式转化为下面这样的

const flattenState = {
    1: {id: 1, name: 'RMA', champion: 13},
    2: {id: 2, name: 'ACM', champion: 7},
    3: {id: 3, name: 'MUN', champion: 4},
    4: {id: 4, name: 'ARS', champion: 0}
}

上面这一种形式就是使用唯一的id来作为键值对的键,把上面数组的某一项作为键值对的值。

对数据操作

// 删除
const deleteData = (id) => {
    delete flattenState[id]
    setTeams(flattenState)
}

// 修改id为'1'的
const modifyData = (id, val) => {
    const newTeam = {...Teams[id], champion: val}
    setTeams({...teams, [id]: newTeam})
}

// 查询
const findData = (id) => {
    return teams[id]
}

这样就方便许多了,我们在操作数据的时候就不需要循环了所以时间复杂度变味了O(1),思路也更加清晰了,代码也没有以前那么多了。

4、数组形式flattenState形式相互转化

数组转化为flattenState

const converseArrToObj = (arr) => {
    return arr.reduce((obj, item) => {
        obj[item.id] = item
        return obj
    }, {})
}

flattenState转化为数组

const converseObjToArr = (obj) => {
    const keys = Object.keys(obj)
    return keys.map(key => {
        return obj[key]
    })
}

5、优点

  • 解决数据的冗余
  • 处理数据更加的方便
  • 代码更加清晰

大家所熟知的Redux就是使用的该方式:Normalizing State Shape,大家有兴趣可以看看。

今天的文章就到这里了,大家晚安。。。