使用Redux處理異步問(wèn)題
useSelector,useDispatch
首先,也是最重要的一點(diǎn)。如果你不知道要不要用redux,那么最好不要用。
redux主要解決的問(wèn)題是統(tǒng)一來(lái)源的狀態(tài)管理。
- 全局state存放在store里。
store.getState()
可以獲得state樹(shù)。 - 給store,發(fā)送action可以通過(guò)reducer生成新的state。
store.dispatch({type:SOME_ACTION, data: {})
。 - 訂閱store,或者新的state。
store.subscribe(() => store.getState())
。
React-redux主要解決的是第二條。使用connect
方法把state和actions都作為props注入到了組件里。
比如現(xiàn)在有一個(gè)Counter
組件。increment做為action creator。狀態(tài)就是value++。
那么可以寫(xiě)成:
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呢,畫(huà)風(fēng)一轉(zhuǎn)。整個(gè)顯得清晰了很多。當(dāng)然這里也不能少了redux toolkit的幫助。
要實(shí)現(xiàn)redux應(yīng)用的完全體就少不了要?jiǎng)?chuàng)建redux的store等這些前期的配置工作。為了減少這些繁瑣的配置,redux開(kāi)發(fā)了toolkit這一套工具。項(xiàng)目代碼中都有,可以參考。這里不多介紹。
使用了react-redux之后看起來(lái)就是這樣了。我們?cè)谇捌跊](méi)有多做action(action creator)和reducer的介紹。突然出現(xiàn)不能體現(xiàn)它的簡(jiǎn)化后的好處。有一點(diǎn),action和reducer通常都放在不同的地方。使用起來(lái)不是十分方便。
在新的實(shí)現(xiàn)中這些都在slice文件中,方便統(tǒng)一的管理。維護(hù)起來(lái)也好很多。
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的部分基本不用處理。它會(huì)自動(dòng)生成出來(lái)action creator。
react-redux的connect方法也省去了。
代替的方案是useSelector和useDispatch兩個(gè)方法。
在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樹(shù)對(duì)應(yīng)到這個(gè)組件的狀態(tài) - 2. 使用
useDispatch
獲取dispatch方法,可以發(fā)送action - 3. 在處理add點(diǎn)擊的時(shí)候調(diào)用dispatch方法發(fā)送
increment()
action creator生成的action。
處理異步
在一般的開(kāi)發(fā)中需要處理很多的網(wǎng)絡(luò)請(qǐng)求,緩存讀寫(xiě)等情況。這些都是異步的。
Redux提供了兩種方法來(lái)處理異步的情況:
- createAsyncThunk
- RTK Query, redux toolkit query
下面主要通過(guò)異步緩存讀寫(xiě)來(lái)演示如何使用這兩種方法。
在React Native里用來(lái)處理簡(jiǎn)單的字符串存取的庫(kù)一般是
@react-native-async-storage/async-storage
import:
import AsyncStorage from '@react-native-async-storage/async-storage';
讀、寫(xiě),刪除:
// inside a async function const ret = await AsyncStorage.getItem('@your-key'); await AsyncStorage.setItem('@your-key', xxx-xxx-xxx); await AsyncStorage.removeItem('@your-key');
createAsyncThunk
很久以前,有一個(gè)用redux就用過(guò)的redux插件叫做redux-thunk
。
現(xiàn)在我們有了createAsyncThunk
。
在使用的時(shí)候和前文提到的slice的套路基本一致。首先我們來(lái)新建一個(gè)slice叫做authSlice
。
在里面填空比如:name,initialState。
reducers為空對(duì)象,處理非異步的情況。
新增的是:
- 新建相關(guān)的thunk
extraReducers
新建thunk
const authenticate = createAsyncThunk<boolean, string, any>( 'users/auth', async (token: string) => { try { await AsyncStorage.setItem(GITHUB_TOKEN_KEY, token); return true; } catch (e) { console.error('ERROR:', e); return false; } }, ); const authSlice = createSlice({ name: 'auth', initialState: { authed: false, }, reducers: {}, });
添加extraReducers
異步的thunks就放在extraReducers里:
const authSlice = createSlice({ name: 'auth', initialState: { authed: false, }, reducers: {}, extraReducers: builder => { builder.addCase(authenticate.fulfilled, state => { state.authed = true; }); builder.addCase(removeToken.rejected, state => { state.authed = false; }); }, });
最后export出去:
export { authenticate, removeToken, authSlice };
后續(xù)還要在store里綁定reducer。
export const store = configureStore({ reducer: { counter: counterSlice.reducer, auth: authSlice.reducer }, });
使用上和之前的countSlice一樣:
// 讀取state值const authed = useSelector((state: RootState) => state.auth.authed);
在TokenScreen.tsx文件里可以看到具體代碼。
發(fā)出thunk:
const dispatch = useAppDispatch(); // 1 try { const ret = await dispatch(authenticate(text)).unwrap(); // 2 if (ret) { console.log('>result action: ', 'DONE'); } navigation.replace('Tabs'); } catch (e) { // TODO: deal with the error }
拿到useAppDispatch
方法。在src/store.ts文件里。
本質(zhì)就是useDispatch
。
處理分發(fā)的thunk的結(jié)果的時(shí)候可以用redux提供的unwrap
方法直接得到結(jié)果。
在catch語(yǔ)句里處理錯(cuò)誤。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
React onBlur回調(diào)中使用document.activeElement返回body完美解決方案
這篇文章主要介紹了React onBlur回調(diào)中使用document.activeElement返回body完美解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04Next+React項(xiàng)目啟動(dòng)慢刷新慢的解決方法小結(jié)
本文主要介紹了Next+React項(xiàng)目啟動(dòng)慢刷新慢的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04使用Ant Design Anchor組件的一個(gè)坑及解決
這篇文章主要介紹了使用Ant Design Anchor組件的一個(gè)坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04React組件創(chuàng)建與事件綁定的實(shí)現(xiàn)方法
react事件綁定時(shí)。this并不會(huì)指向當(dāng)前DOM元素。往往使用bind來(lái)改變this指向,今天通過(guò)本文給大家介紹React事件綁定的方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-12-12React中使用Workbox進(jìn)行預(yù)緩存的實(shí)現(xiàn)代碼
Workbox是Google Chrome團(tuán)隊(duì)推出的一套 PWA 的解決方案,這套解決方案當(dāng)中包含了核心庫(kù)和構(gòu)建工具,因此我們可以利用Workbox實(shí)現(xiàn)Service Worker的快速開(kāi)發(fā),本文小編給大家介紹了React中使用Workbox進(jìn)行預(yù)緩存的實(shí)現(xiàn),需要的朋友可以參考下2023-11-11淺談React?Refs?使用場(chǎng)景及核心要點(diǎn)
本文主要介紹了React?Refs?使用場(chǎng)景及核心要點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06學(xué)習(xí)ahooks useRequest并實(shí)現(xiàn)手寫(xiě)
這篇文章主要為大家介紹了學(xué)習(xí)ahooks useRequest并實(shí)現(xiàn)手寫(xiě)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Ant?Design?組件庫(kù)按鈕實(shí)現(xiàn)示例詳解
這篇文章主要介紹了Ant?Design?組件庫(kù)按鈕實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪</P><P><BR>2022-08-08React?中如何將CSS?visibility?屬性設(shè)置為?hidden
這篇文章主要介紹了React中如何將CSS?visibility屬性設(shè)置為?hidden,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05