redux-saga的基本使用
yarn add redux-saga
mysaga.js 定义saga文件
import {call, put, takeEvery} from 'redux-saga/effects' // 模拟登陆接口 const UserService = { login(name) { return new Promise((resolve, reject) => { console.log('login', name) setTimeout(() => { if(name === '小明') { console.log('suc') resolve({name: '小明'}) } else { reject({name: '用户名或密码错误'}) } }, 1000) }) } } function* loginHandle(action) { // generator将异步操作改为同步 console.log('loginHandle', action) try{ const res = yield call(UserService.login, action.name) //call执行UserService.login,并且将action.name当参数传递过去 console.log('res', res) yield put({type: 'requestSuccess', res}) // put和dispatch类似,执行reducer } catch (error) { console.log('error', error) yield put({type: 'requestFailure', error}) } } function* mySaga() { yield takeEvery('login', loginHandle) // 类似于将函数重命名,调用login则会执行loginHandle,并且将login得参数传递过去 } export default mySaga
store.js 存储公共状态文件
import {createStore, combineReducers, applyMiddleware} from 'redux' import thunk from 'redux-thunk' // 此处没有用到 import createSagaMiddleware from 'redux-saga' // 引入createSagaMiddleware import mySaga from '../mySage' const initalLogin = { isLogin: false, // 是否登陆 loading: false, // 登陆状态 name: '', error: '' } const sagaMiddleware = createSagaMiddleware() // 创建中间件 function loginReducer(state = {...initalLogin}, action) { console.log('loginReducer', action) switch (action.type) { case 'requestLogin': return {...state, loading: true} case 'requestSuccess': return {...state,isLogin: true, loading: false} case 'requestFailure': return {...state,isLogin: false, loading: false, error: action.error.name} default: return state } } const store = createStore( combineReducers({user: loginReducer}), // applyMiddleware(thunk) applyMiddleware(sagaMiddleware) // 将中间件放入applyMiddleware ) sagaMiddleware.run(mySaga) // 此处必须执行run() export default store
loginPage.js 具体调用页面
import React, {Component} from 'react'; import {Redirect} from 'react-router-dom' import {connect} from "react-redux"; class LoginPage extends Component { constructor(props) { super(props); this.state = { name: '' } } changeName = (event) => { this.setState({ name: event.target.value }) } render() { const {isLogin,loading, location, loginSuccess, login, error} = this.props console.log('loginPage', this.props) const {name} = this.state if(isLogin) { const {redirect = '/'} = location.state || {} return <Redirect to={redirect} /> } return ( <div> <h1>loginPage</h1> <input type="text" value={name} onChange={this.changeName}/> <button onClick={() => login(name)}>{loading ? '登录中': '登录'}</button> { error && (<p>{error}</p>) // 有错误信息则显示 } </div> ); } } const mapStateToprops = state => { return { isLogin: state.user.isLogin, loading: state.user.loading, error: state.user.error } } const mapDispatchToProps = { // 方法映射到props上 // loginSuccess: () => { // return {type: 'requestSuccess'} // }, // loginSuccess: () => dispatch => { // dispatch({type: 'requestLogin'}) // setTimeout(() => { // dispatch({type: 'requestSuccess'}) // }, 2000) // }, login : (name) => { // 这里会接收到调用login方法传得得参数 return ({type: 'login', name}) } } export default connect(mapStateToprops, mapDispatchToProps)(LoginPage)
以下是数据传递方式