寫過vue就知道有vue有提供vuex來做資料(state)的集中管理,那麼React就是藉由Redux來達成,不過讓我有點訝異的應該是React 跟 Redux沒有關係,我以為Redux和React的關係就像vue和vuex一樣(殊不知完全不是)!
在找資料的過程中比對目前的官網文件,其實看得有點痛苦,一下子import React-Redux,一下子import Redux,這兩個難道是不一樣的東西嗎,花了一點時間才理解,原來React-Redux是React與Redux的橋樑
Redux一個用於應用程式狀態管理的開源JavaScript庫。Redux經常與React搭配運用,但其也可以獨立使用 (來自維基百科的解釋
先來認識四個重要的名詞
首先,先安裝Redux 和 React-Redux
npm install redux react-redux
reducer 會有兩個參數,第一個為初始狀態的state,即initalState,第二個則是傳入action
接下來根據傳入的action的類型,對資料做不同的操作(對當前數字做加減),記得一定要在default回傳原值,才能處理那些沒被定義的action type
const initialState = {
count: 0
}
export default function reducer(prevState = initialState, action) {
switch (action.type) {
case "ADD_ONE":
return {
...prevState,
count: prevState.count +1
}
case "MINUS_ONE":
return {
...prevState,
count: prevState.count -1
}
default:
return prevState;
}
}
創建完reducer後要在index.js引入createStore ,並且傳入reducer,假設我有多個reducer呢?那就可以引用redux提供的combineReducers方法來整合多個reducer,再一口氣傳入全部reducer
React透過provider接收傳入的store ,可以讓所有的子組件透過props都拿到state,每個專案都應該只有一個store
在index.js建立一個provider,並且包住< App/>
import { createStore } from 'redux';
import { Provider } from 'react-redux'
import reducer from './redux/reducers';
const store = createStore(reducer);
store.subscribe(()=>{
console.log(store.getState())
})
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
connect的概念是將Redux與UI組件結合,Redux負責資料處理,UI組件只要單純根據輸入的資料做畫面渲染即可,這邊有運用的HOC(High order component)的概念,傳入mapStateToProps、mapDispatchToProps,以及原先寫好的class component(Counters)後,會加上一些方法後回傳一個全新的物件
import { connect } from 'react-redux'
import Counters from './Counters'
import { addOne, minusOne } from './redux/action'
const mapStateToProps = (state) => {
return {
count: state.count
}
}
const mapDispatchToProps = dispatch => {
return{
addOne:()=>{
dispatch(addOne())
},
minusOne: () => {
dispatch(minusOne());
},
}
}
const Counter = connect(
mapStateToProps,
mapDispatchToProps
)(Counters);
export default Counter
connect 共有4個參數,但我看大部分的情境只會用到前面兩個,所以後面兩個參數就不介紹了
function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)
mapStateToProps
將store的state 對應成props state,日後如果state有更新,那麼mapStateToProps也會跟著改變
mapDispatchToProps
將store的dispatch 對應成為props dispatch,假設connect沒有傳入,預設會帶入dispatch
這是被傳入的Counters component,透過props拿到剛剛connect帶入的mapStateToProps與mapDispatchToProps,此時點擊按鈕就能成功修改遠在天邊的initialState.count
import React, { Component, Fragment } from 'react';
class Counters extends Component {
render() {
const { addOne, minusOne, count} = this.props
return (
<Fragment>
<h1>{count}</h1>
<button onClick={addOne}>+1</button>
<button onClick={minusOne}>-1</button>
</Fragment>
)
}
}
export default Counters
之前問有學過React的朋友,他們覺得最難理解的是那一個部分?大部分都回Redux,的確是名不虛傳XD