簡體   English   中英

使用 React/Redux saga 將數據從組件傳遞到 action 和 saga

[英]Pass data from component to action and saga using React/Redux saga

我在 Redux Saga 中使用 React。 當我嘗試使用 this.props.dispatch({type: CreateActionType.CREATE_ASYNC}) 在我的組件中執行 Saga Effect 時; 什么都沒有發生,它不會被執行。

當我在 index.js 中 console.log this.props.data 時,它是空的

如果這里缺少必要的信息,請告訴我。

api.js

export const create = (params) => {
const dataList = {
    data: {data1: 1, data2: 2,},
    statusCode: 200,
}
    return dataList;
};

sagas.js

import { put, call, takeEvery , all } from 'redux-saga/effects'
import { create } from '../api';

import * as CreateActionType from './constants';

export function* createAsync(action) {
    const result = yield call(create, action.params);
    const statusCode = result.statusCode;

    if (statusCode === 200) {
        yield [
            put({ type: CreateActionType.CREATE_SUCCESS, params: result.data }),
        ];
    } else {
        console.warn("createAsync error", result.data);
    }
};

function* WatchCreate() { 
    yield [
        takeEvery(CreateActionType.CREATE_ASYNC, createAsync),
    ]  
}

export default function* rootSaga() {
    yield all([
        WatchCreate(),
    ])
}

商店.js

import * as CreateActionType from './constants';
import { combineReducers } from 'redux';

const defaultState = {
    data: null,
}

function CreateStore(state = defaultState, action) {

    switch (action.type) {
        case CreateActionType.CREATE_SUCCESS:
            return {
                ...state,
                createStatus: true,
            };
        default:
            return state;
    }
};

const rootReducer = combineReducers({
    CreateStore,
})

export default rootReducer;

索引.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as CreateActionType from './constants';

class CreateNote extends Component {
    constructor(props){
        super(props);

        this.state = {};
    };

    componentDidMount() {
        this.props.dispatch({
            type: CreateActionType.CREATE_ASYNC,
        });
    };

    render() {
        return <p>{this.props.data}</p>;
    }
}

const mapStateToProps = (state) => {        
    return state.CreateStore;
};

export default connect(mapStateToProps)(CreateNote);

configstore.js

import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootSaga from './container/sagas';
import rootReducer from './container/stores';

export default function ConfigureStore() {
    const sagaMiddleware = createSagaMiddleware();

    const store = createStore(rootReducer,
        applyMiddleware(sagaMiddleware)
    );

    sagaMiddleware.run(rootSaga);

    return store;
}

很難說哪里出了問題,因為有很多代碼。

假設 saga 實際上正在運行,你永遠不會對返回的數據做任何事情,這就解釋了為什么this.props.data為空。 你可以試試這個。

 case CreateActionType.CREATE_SUCCESS:
        return {
            ...state,
            createStatus: true,
            data: action.params.data,
        };

如果您不確定 sagas 是否正在運行,您應該在 api.js 和 sagas.js 中添加一些日志記錄調用。

我看不出為什么傳奇不應該工作的任何理由,但您可以嘗試進一步簡化它。 我認為產生一系列效果與產生單一效果相比沒有任何好處。

export default function* rootSaga() {
    yield takeEvery(CreateActionType.CREATE_ASYNC, createAsync)
}

嘗試簡化這個

function* WatchCreate() { 
    yield [
        takeEvery(CreateActionType.CREATE_ASYNC, createAsync),
    ]  
}

export default function* rootSaga() {
    yield all([
        WatchCreate(),
    ])
}

export default function* rootSaga() {
    yield all([
        takeEvery(CreateActionType.CREATE_ASYNC, createAsync),
    ])
}

我發現盡可能在效果級別(同步創建的對象)上工作更容易,而不是嵌套的傳奇。 您的問題可能是您調用WatchCreate並嘗試使用返回值,盡管它沒有返回值。

你的動作傳奇有一個參數createAsync(action) 您需要在調用函數時傳遞數據,就像這樣takeEvery(createActionType.CREATE_ASYNC, createAsync, action) 以下面這個例子為例。

import { call, put, SagaReturnType, takeLatest } from '@redux-saga/core/effects'
import axios, { AxiosResponse } from 'axios'
import * as ActionCreators from './actionCreators'
import * as ActionTypes from './actionTypes'

type apiResponse = SagaReturnType<typeof deleteUser>

const deleteUser = async (userId: string): Promise<AxiosResponse> => {
    return axios.delete(`localhost:8081/users/${userId}`)
}

function* deleteUserSaga(user: User) {
    try {
        if (user.userId) {
            const response: apiResponse = yield call(deleteUser, user.userId)

            if (response.status === 200) {
                put(ActionCreators.deleteSuccess(user))
            }

            throw new Error('User delete unsuccessful')
        }
    } catch (err) {
        put(ActionCreators.deleteError(err))
    }
}

// eslint-disable-next-line
export default function* DeleteUserWatcher(user: User) {
    yield takeLatest(ActionTypes.DELETE_BEGIN, deleteUserSaga, user)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM