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)

以下是数据传递方式

 

 

posted @ 2021-01-14 11:43  陈小作  阅读(860)  评论(0编辑  收藏  举报