理解
redux 的异步大体上可以分成两种
1.thunk (thunk 会把dispatch事件写在个个需要发送的组件中,所以如果过多会让主件显得很臃肿)
2.sage(有点类似java中的MVP模式,让组件和请求业务分离,所有我觉得选择sage会更好)
下面的demo中会对两种用法进行介绍。
工程准备阶段
- yarn add redux
- yarn add redux-thunk
- yarn add redux-saga
- yarn add axios
- yarn add react-redux
- 添加插件👇 在 babel.config.js文件中
- yarn add metro-react-native-babel-preset
- yarn add @babel/plugin-proposal-decorators
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
]
]
};
整个工程结构 主要分为以下部分
1.reudcer部分
2.sage部分
3.store部分
4.这里主要讲得是sage部分,其他部分网上已经有很多了,但是好像没有多少demo。 下面会把demo给出来。sage部分在 工程主件的page4.js 中有用到。page3.js为thunk,page2.js为一般的connect用法。
5.在page2.js和page3.js中分别对connect使用了两种常用的方法。
sage 的使用方法讲解
sage中最重要的是三个状态。
- worker saga
做所有的工作,如调用 API,进行异步请求,并且获得返回结果- watcher saga
监听被 dispatch 的 actions,当接收到 action 或者知道其被触发时,调用 worker saga 执行任务- root saga
立即启动 sagas 的唯一入口- 注意要点通常情况下root和watcher 最好写在一个方法中。代码👇
import {call, put, takeEvery, takeLatest} from 'redux-saga/effects';
import axios from 'axios';
//3.worker saga
function* showPostsAsync(params) {
//这里的params 为'TEST'对应的整个actions
//比如actions为 {"params": {"h": "dsfs", "tag": "df"}, "type": "TEST"}
//那么对应的params 为 整个actions对象而不是 actions对象里面对应的params 重点。
try {
const response = yield call(
axios.get,
'https://jsonplaceholder.typicode.com/posts',
);
console.log('params', params);
//异步请求之后就会发起actions给reducers,reducer再进行数据修改。
yield put({type: 'success', data: response.data[0].body});
} catch (e) {
yield put({type: 'ERRO', data: e});
}
}
//3.worker saga
function* testConcurrencyAsync(params) {
try {
const response = yield call(
axios.get,
'https://jsonplaceholder.typicode.com/users',
);
console.log('params', params);
yield put({type: 'thunk_SUCCESS', data: response.data[0].name});
} catch (e) {
yield put({type: 'thunk_FAIL', data: e});
}
}
//1.root saga
export default function* rootSaga() {
//这里启动和监听一步写好,不要拆开否则只会运行第一个。之后不再往下运行。
//这里的TEST是page4.js中发送的TEST actions showPostsAsync为接到活动所需要执行的方法。
//2.watcher saga
yield takeLatest('TEST', showPostsAsync);
yield takeLatest('TEST_Concurrency', testConcurrencyAsync);
}
import {call, put, takeEvery, takeLatest} from 'redux-saga/effects';这些元素的使用如果不清楚可以参考https://www.cnblogs.com/libin-1/p/6858558.html
上面代码运行的顺序已经用1.2.3.标注出来。
store中的注册方式
import { createStore,applyMiddleware, } from 'redux';
import reducer from '../reducer/index';
import thunk from 'redux-thunk';
import createSagaMiddleware from 'redux-saga';
import sage from '../sages/index';
const sagaMiddleware = createSagaMiddleware();
const middlewares = [thunk,sagaMiddleware];
const store = createStore(reducer,applyMiddleware(...middlewares));
sagaMiddleware.run(sage);
export default store;
reducer的拆分
//reducer.js 创建一个reducer对象
const defaultState = {inputValue: ''};
const reducer = (state = defaultState, actions) => {
console.log('actions', actions);
switch (actions.type) {
case 'CHANGE_VALUE':
return {...state, inputValue: actions.data};
case 'success':
return {...state, inputValue: actions.data};
case 'ERRO':
return {...state, inputValue: actions.data};
case 'thunk_SUCCESS':
return {...state, thunkData: actions.data};
case 'thunk_FAIL':
return {...state, thunkData: actions.data};
default:
return state;
}
// if (actions.type === 'CHANGE_VALUE') {
// // let newState = JSON.parse(JSON.stringify(state));
// // newState.inputValue = actions.data;
// return {...state,inputValue:actions.data};
// }
// return state;
};
export default reducer;
//注入到combineReducers中进行整合
import { combineReducers } from 'redux';
import reducer from './reducer';
//combineReducers辅助函数的作用是,把一个由多个不同 reducer 函作为 value 的 object,
//合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore
const rootReducer = combineReducers({
reducer,
});
export default rootReducer;
如何sage事件:
sage文件中已经注册了事件的监听。只需要dispatch对应的监听活动即可。
代码地址👇
项目地址
博客引用:
https://www.cnblogs.com/libin-1/p/6858558.html
https://www.jianshu.com/p/e84493c7af35
网友评论