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

cAuth發表於2020-01-03

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,大家有興趣可以看看。

今天的文章就到這裡了,大家晚安。。。

相關文章