React Native填坑之旅--使用react-redux hooks

小紅星閃啊閃發表於2021-11-04

React hooks出來之後又開啟了一道前端造輪子的大門。各種Hooks的工具滿天飛。react-redux也跟上了這波潮流。

專案程式碼在這裡

首先,也是最重要的一點。如果你不知道要不要用redux,那麼最好不要用。

redux主要解決的問題是統一來源的狀態管理。

  1. 全域性state存放在store裡。store.getState()可以獲得state樹。
  2. 給store,傳送action可以通過reducer生成新的state。store.dispatch({type:SOME_ACTION, data: {})
  3. 訂閱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。

相關文章