前端(vue)入門到精通課程:進入學習
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API偵錯工具:
在之前的redux開發中,為了讓元件和redux結合起來,我們使用了react-redux庫中的connect:
但是這種方式必須使用高階函數結合返回的高階元件;
並且必須編寫:mapStateToProps和 mapDispatchToProps對映的函數, 具體使用方式在前面文章有講解;【相關推薦:Redis視訊教學、】
在Redux7.1開始,提供了Hook的方式,在函陣列件中再也不需要編寫connect以及對應的對映函數了
useSelector
的作用是將state對映到元件中:
引數一: 要求傳入一個回撥函數, 會將state傳遞到該回撥函數中; 回撥函數的返回值要求是一個物件, 在物件編寫要使用的資料, 我們可以直接對這個返回的物件進行解構, 拿到我們要使用state中的資料
const { counter } = useSelector((state) => { return { counter: state.counter.counter } })登入後複製引數二: 可以進行比較來決定是否元件重新渲染;
useSelector預設會比較我們返回的兩個物件是否相等;
如何可以比較呢?
- 在useSelector的第二個引數中, 傳入react-redux庫中的
shallowEqual
函數就可以進行比較
import { shallowEqual } from 'react-redux' const { counter } = useSelector((state) => ({ counter: state.counter.counter }), shallowEqual)登入後複製也就是我們必須返回兩個完全相等的物件才可以不引起重新渲染;
useDispatch
非常簡單,就是呼叫useDispatch這個Hook, 就可以直接獲取到dispatch函數,之後在元件中直接使用即可;
const dispatch = useDispatch()
登入後複製
我們還可以通過useStore來獲取當前的store物件(瞭解即可, 不建議直接操作store物件);
我們來使用Redux的Hooks在App元件實現一個計數器, 在App的子元件中實現一個修改message的案例:
首先我們先建立一個簡單的store
// store/modules/counter.js
import { createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: {
counter: 10,
message: "Hello World"
},
reducers: {
changeNumberAction(state, { payload }) {
state.counter = state.counter + payload
},
changeMessageAction(state, {payload }) {
state.message = payload
}
}
})
export const { changeNumberAction, changeMessageAction } = counterSlice.actions
export default counterSlice.reducer
登入後複製
// store/index.js
import { configureStore } from "@reduxjs/toolkit";
import counterSlice from "./modules/counter"
const store = configureStore({
reducer: {
counter: counterSlice
}
})
export default store
登入後複製
要使用react-redux庫需要匯入Provider對App元件進行包裹
import React from "react"
import ReactDOM from "react-dom/client"
import { Provider } from "react-redux"
import App from "./12_Redux中的Hooks/App"
import store from "./12_Redux中的Hooks/store"
const root = ReactDOM.createRoot(document.querySelector("#root"))
root.render(
<Provider store={store}>
<App/>
</Provider>
)
登入後複製
在元件時使用useSelector和useDispatch實現獲取store中的資料和修改store中資料的操作
import React, { memo } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { changeMessageAction, changeNumberAction } from './store/modules/counter'
// 子元件Home
const Home = memo(() => {
console.log("Home元件重新渲染")
// 通過useSelector獲取到store中的資料
const { message } = useSelector((state) => ({
message: state.counter.message
}))
// useDispatch獲取到dispatch函數
const dispatch = useDispatch()
function changeMessage() {
dispatch(changeMessageAction("Hello ChenYq"))
}
return (
<div>
<h2>{message}</h2>
<button onClick={changeMessage}>修改message</button>
</div>
)
})
// 根元件App
const App = memo(() => {
console.log("App元件重新渲染")
// 通過useSelector獲取到store中的資料
const { counter } = useSelector((state) => ({
counter: state.counter.counter
}))
// useDispatch獲取到dispatch函數
const dispatch = useDispatch()
function changeNumber(num) {
dispatch(changeNumberAction(num))
}
return (
<div>
<h2>當前計數: {counter}</h2>
<button onClick={() => changeNumber(1)}>+1</button>
<button onClick={() => changeNumber(-1)}>-1</button>
<Home/>
</div>
)
})
export default App
登入後複製
現在我們已經在元件中使用並且修改了了store中的資料, 但是現在還有一個小問題(效能優化)
當App元件中修改了counter時, App元件會重新渲染這個是沒問題的; 但是Home元件中使用的是message, 並沒有使用counter, 卻也會重新渲染; 同樣的在Home子元件中修改了message, 根元件App也會重新渲染; 這是因為在預設情況下useSelector是監聽的整個state, 當state發生改變就會導致元件重新渲染
要解決這個問題就需要使用useSelector的第二個引數來控制是否需要重新渲染, 我們只需要在useSelector函數中傳入react-redux庫中的
shallowEqual
函數即可, 它內部會自動進行一個淺層比較, 當使用的state中的資料確實發生變化的時候才會重新渲染
import React, { memo } from 'react'
import { useDispatch, useSelector, shallowEqual } from 'react-redux'
import { changeMessageAction, changeNumberAction } from './store/modules/counter'
// 子元件Home
const Home = memo(() => {
console.log("Home元件重新渲染")
const { message } = useSelector((state) => ({
message: state.counter.message
}), shallowEqual)
const dispatch = useDispatch()
function changeMessage() {
dispatch(changeMessageAction("Hello ChenYq"))
}
return (
<div>
<h2>{message}</h2>
<button onClick={changeMessage}>修改message</button>
</div>
)
})
// 根元件App
const App = memo(() => {
console.log("App元件重新渲染")
// 通過useSelector獲取到store中的資料
const { counter } = useSelector((state) => ({
counter: state.counter.counter
}), shallowEqual)
// useDispatch獲取到dispatch函數
const dispatch = useDispatch()
function changeNumber(num) {
dispatch(changeNumberAction(num))
}
return (
<div>
<h2>當前計數: {counter}</h2>
<button onClick={() => changeNumber(1)}>+1</button>
<button onClick={() => changeNumber(-1)}>-1</button>
<Home/>
</div>
)
})
export default App
登入後複製
更多程式設計相關知識,請存取:!!
以上就是一文詳解Redux Hooks的使用細節的詳細內容,更多請關注TW511.COM其它相關文章!