使用React / Redux传奇将数据从组件传递给action和saga

时间:2018-02-25 06:51:13

标签: javascript reactjs react-native redux frontend

我使用React与Redux Saga。当我尝试使用this.props.dispatch({type:CreateActionType.CREATE_ASYNC})在我的组件中执行Saga效果时;什么都没发生,它没有被执行。

当我在index.js中调试this.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(),
    ])
}

store.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;

index.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;
}

2 个答案:

答案 0 :(得分:0)

很难说出现了什么问题,因为有很多代码。

假设saga实际上正在运行,你永远不会对返回的数据做任何事情,这解释了为什么this.props.data为空。你可以试试这个。

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

如果您不确定传奇是否正在运行,您应该在api.js和sagas.js中添加一些日志记录调用。

我没有看到为什么传奇不能起作用的原因,但你可能会尝试简化它。我不认为产生效果阵列与产生单一效果有任何好处。

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

答案 1 :(得分:0)

你的动作传奇有一个参数 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)
}