React hooks出來之後又開啟了一道前端造輪子的大門。各種Hooks的工具滿天飛。react-redux也跟上了這波潮流。
專案程式碼在這裡
首先,也是最重要的一點。如果你不知道要不要用redux,那麼最好不要用。
redux主要解決的問題是統一來源的狀態管理。
- 全域性state存放在store裡。
store.getState()
可以獲得state樹。 - 給store,傳送action可以通過reducer生成新的state。
store.dispatch({type:SOME_ACTION, data: {})
。 - 訂閱store,或者新的state。
store.subscribe(() => store.getState())
。
React-redux主要解決的是第二條。使用connect
方法把state和actions都作為props注入到了元件裡。
比如現在有一個Counter
元件。increment做為action creator。狀態就是value++。那麼可以寫成:
function Counter(props) {
// ...
return (<Button onClick={() => props.increment()}>+</Button>)
}
const mapStateToProps = (state) => ({
value: state.value,
});
const mapActionToProps = (dispatch) => ({
increment: dispatch(increment()),
})
connect(mapStateToProps, mapActionToProps)(Counter);
大概就是上面這樣的。使用了react-redux的hooks呢,畫風一轉。整個顯得清晰了很多。當然這裡也不能少了redux toolkit的幫助。
要實現redux應用的完全體就少不了要建立redux的store等這些前期的配置工作。為了減少這些繁瑣的配置,redux開發了toolkit這一套工具。專案程式碼中都有,可以參考。這裡不多介紹。
使用了react-redux之後看起來就是這樣了。我們在前期沒有多做action(action creator)和reducer的介紹。突然出現不能體現它的簡化後的好處。有一點,action和reducer通常都放在不同的地方。使用起來不是十分方便。
在新的實現中這些都在slice檔案中,方便統一的管理。維護起來也好很多。
import { createSlice } from '@reduxjs/toolkit';
export const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
increment: state => {
state.value += 1;
},
decrement: state => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
});
// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
這是使用了redux toolkit的好處。action的部分基本不用處理。它會自動生成出來action creator。
react-redux的connect方法也省去了。代替的方案是useSelector和useDispatch兩個方法。在ReduxCounter元件裡:
// ...
const ReduxCounter: React.FC<ReduxCounterProps> = props => {
// ...
const count = useSelector((state: RootState) => { // 1
return state.counter.value;
});
const dispatch = useDispatch(); // 2
const onAdd = () => dispatch(increment()); //3
return (
<View>
<Text>{count}</Text>
</View>
<View style={styles.buttonWrapper}>
<TouchableHighlight style={styles.button} onPress={onAdd}>
<View style={styles.buttonInsider}>
<Text>+</Text>
</View>
</TouchableHighlight>
);
};
export { ReduxCounter };
// 1. 使用useSelector
獲取state樹對應到這個元件的狀態
// 2. 使用useDispatch
獲取dispatch方法,可以傳送action
// 3. 在處理add點選的時候呼叫dispatch方法傳送increment()
action creator生成的action。