【问题标题】:Pass data from component to action and saga using React/Redux saga使用 React/Redux saga 将数据从组件传递到 action 和 saga
【发布时间】:2018-08-04 21:03:09
【问题描述】:

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

当我在 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(),
    ])
}

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

【问题讨论】:

  • 创建代码sn-p并分享,你会得到更多反馈
  • 这是基本的 redux 传奇
  • 你应该调试它。如果控制台中没有错误消息,请添加一些 console.log 调用以查看执行与否。
  • 您越容易为他人提供帮助,就越有可能帮助您。

标签: javascript reactjs react-native redux frontend


【解决方案1】:

很难判断出了什么问题,因为代码非常多。

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

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

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

我看不出 sagas 不起作用的任何原因,但您可以尝试进一步简化它。我认为产生效果数组与产生单一效果相比没有任何好处。

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

【讨论】:

  • @Lid 我有来自 api.js 的数据,我用 componentWillReceiveProps(nextProps) { this.setState({content: nextProps.data}); 固定在 index.js }。谢谢。
  • 为什么要为此使用组件状态?您正在使用 redux。在 redux 中保持状态并在组件中使用 props 要简单得多。
【解决方案2】:

试着简化一下

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),
    ])
}

我发现尽可能多地处理效果级别(同步创建的对象)而不是嵌套的 sagas 更容易。 您的问题可能是您调用WatchCreate 并尝试使用返回值,尽管它没有。

【讨论】:

  • @NguyễnThànhNam Mh。我注意到您还将put 放在一个数组中,这是不必要的。所以你是说你的状态仍然有 null ?你检查过你所有的 sagas 都被断点/调试器调用了吗?您是否在开发工具中看到所有预期的操作?
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2018-09-07
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 2018-12-13
    相关资源
    最近更新 更多