redux、react-redux
目录结构
入口文件(index.js)
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Router from "../src/router"
import {store} from "./store/index"
import {Provider} from "react-redux"
ReactDOM.render(
<Provider store={store}>
<Router></Router>,
</Provider>,
document.getElementById('root')
);
1.新建store文件夹
(1)新建index.js文件
import {createStore} from "redux"
import {defReducers} from "./reducers/index"
const store = createStore(defReducers);
export {
store
}
(2)新建reducers文件夹
新建index.js文件
export function defReducers(state,action){
switch (action.type) {
case 'login_suceeess':
console.log(action)
break;
default:
break;
}
return Object.assign({},state,action)
}
(3)home文件‘
index.js
import React, { Component } from 'react';
import {connect} from "react-redux"
class Home extends Component {
render() {
return (
<div>
<button onClick={this.handleTakeEvery}>点击发送TakeEvery</button>
<button onClick={this.handleTakeLatest}>点击发送TakeLatest</button>
<button onClick={this.handleThrottle}>点击发送Throttle</button>
</div>
);
}
handleTakeEvery=()=>{
this.props.dispatch({
type:'takeEvery',
user:{
username:'1903A',
password:'123456'
}
})
}
handleTakeLatest=()=>{
this.props.dispatch({
type:'takeLatest',
user:{
username:'1903B',
password:'123456'
}
})
}
handleThrottle=()=>{
this.props.dispatch({
type:'throttle',
user:{
username:'1903C',
password:'123456'
}
})
}
}
export default connect()(Home);
效果图
redux-saga
api:takeEvery,takeLatest,throttle
从 Saga 内触发异步操作(Side Effect)总是由 yield 一些声明式的 Effect 来完成的 , 一个 Saga 所做的实际上是组合那些所有的 Effect,共同实现所需的控制流。使用上是用yield Effects的方式来完成,Effect包括
- call: yield call(Generator, param) yield一个call,命令middleware以参数param调用函数 到Generator,saga等待Generator执行之后,接收返回值继续执行,call是堵塞的,就是等待执行完再继续执行,返回的是执行完正常返回的结果.
- take: 是阻塞的,只有监听到他(action.type),才会继续往下执行.也就是说创建一个effect的描述信息,用来命令middleware在Store上等待指定action,在发起与他相匹配的action之前,Generator将暂停.
- put: 类似dispatch方法,触发一个action,用来命令middleware向Store发起一个action请求,而且是非阻塞的
- fork: 非阻塞的,遇到它不需要等待他执行完毕,就可以继续往下执行,fork返回的是一个任务,可以被取消
- cancel: 针对fork方法返回的任务,进行取消
- select: 可以从全局state中获取状态
- saga: 就是用* 注册的函数,一个函数就是一个saga
- effect: 上面的call,put,take...就是effect
takeEvery 这个方法用来监听一个type值是'takeEvery'的action,当这个action
//被提交之后,先不去到reducer里面,而是被监听拦截了---执行自己的函数;
//自己的函数执行完毕之后,再去到达reducer里面;
//每次监听到type是takeevery的action进行调用,都会去执行回调函数;
takeLatest 防抖式的监听;
//每次点击触发,都会清除上一次正在执行的异步任务,只去保留最后一次请求;----;
throttle ---参数-----第一个ms--时间,第二个是监听的action的名字; 第三个是个回调函数;
// 匹配到一个action之后,会执行一个异步任务,同时会把这个执行的异步任务的最近的任务,放在底层buffer里面缓存起来;
//当执行的任务执行完毕之后,会把----缓存的任务也一块执行;
//一段时间内执行一次
1.在store下新建sagas文件夹及index.js文件
index.js
//先引入saga的辅助函数
import { call, put, select, takeEvery, takeLatest, throttle } from "redux-saga/effects"
export function* defSaga() {
yield takeEvery('takeEvery', function* () {
//takeEvery 这个方法用来监听一个type值是'takeEvery'的action,当这个action
//被提交之后,先不去到reducer里面,而是被监听拦截了---执行自己的函数;
//自己的函数执行完毕之后,再去到达reducer里面;
//每次监听到type是takeevery的action进行调用,都会去执行回调函数;
// console.log('takeEvery')
let user = yield select(state => state.user);
console.log(user)
})
// takeLatest 防抖式的监听;
//每次点击触发,都会清除上一次正在执行的异步任务,只去保留最后一次请求;----;
yield takeLatest('takeLatest', function* () {
let user = yield select(state => state.user);
console.log(user);
})
// throttle ---参数-----第一个ms--时间,第二个是监听的action的名字; 第三个是个回调函数;
// 匹配到一个action之后,会执行一个异步任务,同时会把这个执行的异步任务的最近的任务,放在底层buffer里面缓存起来;
//当执行的任务执行完毕之后,会把----缓存的任务也一块执行;
//一段时间内执行一次
yield throttle(2000, 'throttle', function* () {
let user = yield select(state => state.user);
console.log(user);
})
}
2.store/index.js
import {createStore,applyMiddleware} from "redux"
import {defReducers} from "./reducers/index"
import createSagaMiddleware from "redux-saga"
//自己定义的关于处理异步的saga文件;
import {defSaga} from "./sagas/index"
//创建出来saga这个中间件;
const sagaMiddleware = createSagaMiddleware();
//把创建好的sagaMiddleware 给通过applyMiddleware 放在redux里面使用;
const store = createStore(defReducers,applyMiddleware(sagaMiddleware));
//运行saga;
sagaMiddleware.run(defSaga)
export {
store
}
3.home.js
import React, { Component } from 'react';
import {connect} from "react-redux"
class Home extends Component {
render() {
return (
<div>
<button onClick={this.handleTakeEvery}>点击发送TakeEvery</button>
</div>
);
}
handleTakeEvery=()=>{
this.props.dispatch({
type:'takeEvery',
user:{
username:'1903A',
password:'123456'
}
})
}
}
export default connect()(Home);
入口文件(index.js)
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Router from "../src/router"
import {store} from "./store/index"
import {Provider} from "react-redux"
ReactDOM.render(
<Provider store={store}>
<Router></Router>,
</Provider>,
document.getElementById('root')
);