Redux-saga及Dva
Redux-saga
简介
使用量较高的一种redux形式
使用阿里系的脚手架工具
1.dva
2.umi
Saga与Thunk的区别
- redux-saga使用率更高
- redux-thunk
- 将异步数据请求的任何和非异步的任务都放在一起了, 乱锅炖
- redux-sage
- 只处理异步任务
- 非异步任务还是放给组件做比较合适
- redux-saga会将异步任务放入到一个 任务池
Dva 数据流
— redux 之 redux-saga 使用版本
-
关注点
- models 创建redux数据块的
- index.js 激活redux数据块
- routes 使用redux数据块的 — 页面
核心知识
store结构
const store={ //命名空间 namespace:'数据块名', // 定义数据 state={}, // 动作创建者(generator函数语法: * + yield) effects:{ // (动作函数参数 comPrarms:组件触发传入参数,{call,put} call:处理异步任务,put发送action至reducers) *getMovies(comParams,{call,put}){ const result = yield call(异步任务名,传入参数); const action={type:"GET_MOVIES",payload:result} yield put(action) } } , // 数据操作者(输入,修改,输出数据,单一数据源,纯函数,数据只读) reducers:{ // state 为定义的数据,action为effects发送过来的方法 GET_MOVIES(state,action){ // 修改数据并返回 return {...state} } } }
页面结构
// 使用connect高阶组件将store中的数据和方法通过props发送给组件 import { connect } from "_dva@2.4.1@dva"; export default connect((state) => {return state.数据块名?;})(Index); // 页面组件的参数中就可以解构得到dispatch和数据块中的数据,并通过dispatch就可以触发store中effects中的方法并传参 dispatch({ type: "数据块名称/effects方法名", payload: { 'payload就是传给effects参数(一般为数据请求参数)' }, });
快速上手
数据请求渲染案例
安装dva-cli
$ cnpm install dva-cli -g
快速创建项目
$ dav new 项目名称
打造store
src/models/movie.js下
const movieStore={
// Todo 1. 命名空间
namespace:'movieStore',
// Todo 2. 定义state
state:{movie:null},
// Todo 3.定义动作创建者(effects中写generrator函数:* + yield)
effects:{
*getMovie(comPrarms,{call,put}){
// comParams 是组件发送过来的参数 {type,payload}
// call用于发送异步数据请求
// put 用于发送effects创建的action给reducers
const result =yield call(service.fetchMovies,comParams.payload)
const action={
type:'GET_MOVIE',
payload:result?.data.content,
}
yield put(action)
}
},
// Todo 4.定义reducers 操作数据(注意单一数据源,不能直接修改源数据,需要进行拷贝)
reducers:{
GET_MOVIE(state,action){
return {...state,movies:action.payload}
}
}
};
export default movieStore;
激活store
src/index.js下
app.model(require("./models/movie").default);
页面组件中使用
src/routes/IndexPage.js
// dva中引入connect高阶函数
import { connect } from "_dva@2.4.1@dva";
import React, { useEffect } from "react";
const Index = ({ dispatch, movies }) => {
useEffect(() => {
// dispatch激活effects中的方法
dispatch({
//数据块名称/effects方法名
type: "moiveStore/getMovies",
// payload就是进行effects所需的参数(一般为数据请求参数)
payload: { cid: 17 },
});
}, []);
return <div>
<ul>
{
!movies.length
?
(<div>加载中....</div>)
:
(movies?.map((item) => (<li key={item.id}>{item.d_title}</li>)))
}
</ul>
</div>
};
// Dva项目中的connect会将通过回调函数来获取用于获取数据和方法,并以props传入组件
// export default connect((state)=>{return state.数据块名称})(Index)
export default connect((state) => {
return state.movieStore;
})(Index);