使用async react-select与redux-saga

时间:2017-03-28 14:52:03

标签: redux redux-saga react-select

我尝试实现异步react-select(Select.Async)。问题是,我们想在redux-saga中进行提取。因此,如果用户键入内容,则应触发获取操作。然后佐贺取出记录并将它们保存到商店。这项工作到目前为止。 不幸的是,loadOptions必须返回一个promise或者应该调用回调。由于新检索的选项通过更改属性进行传播,因此我看不到将 Select.Async 与saga一起使用来执行异步提取调用。有什么建议吗?

 <Select.Async
   multi={false}
   value={this.props.value}
   onChange={this.onChange}
   loadOptions={(searchTerm) =>  this.props.options.load(searchTerm)}
  />

我有一个hack,我将回调分配给一个类变量并在componentWillReceiveProps上解析它。这样丑陋并且无法正常工作,所以我寻求更好的解决方案。

由于

2 个答案:

答案 0 :(得分:13)

redux-saga用于处理副作用,例如异步接收react-select的选项。这就是你应该将异步内容留给redux-saga的原因。我从未使用react-select,但只要查看文档,我就会这样解决:

您的组件变得非常简单。只需从您的redux商店获取valueoptions即可。 optionsRequestedOPTIONS_REQUESTED操作的动作创建者:

const ConnectedSelect = ({ value, options, optionsRequested }) => (
  <Select
    value={value}
    options={options}
    onInputChange={optionsRequested}
  />
)

export default connect(store => ({
  value: selectors.getValue(store),
  options: selectors.getOptions(store),
}), {
  optionsRequested: actions.optionsRequested,
})(ConnectedSelect)

传奇定义会监视由OPTIONS_REQUESTED触发的onInputChange操作,从服务器加载给定searchTerm的数据,并调度OPTIONS_RECEIVED操作以更新redux存储。< / p>

function* watchLoadOptions(searchTerm) {
  const options = yield call(api.getOptions, searchTerm)
  yield put(optionsReceived(options))
}

换句话说:让您的Component尽可能纯净并处理redux-saga

中的所有副作用/异步调用

我希望这个答案对你有用。

答案 1 :(得分:0)

主要思想是,您能够使用来自以下位置的应用程序上下文来调度redux动作

import React from 'react';
import { connect } from 'react-redux';

import Select from '@components/Control/Form/Skin/Default/Select';
import { reduxGetter, reduxSetter, required as req } from '@helpers/form';
import { companyGetTrucksInit } from "@reduxActions/company";

import AppContext from '@app/AppContext';

const FIELD_NAME = 'truck';

export const getReduxValue = reduxGetter(FIELD_NAME);
export const setReduxValue = reduxSetter(FIELD_NAME);

const SelectCompanyTruck = (props) => {
    const {
        required,
        validate=[]
    } = props;

    const vRules = [...validate];

    if (required)
        vRules.push(req);


    return (
        <AppContext.Consumer>
            {({ dispatchAction }) => (
                <Select
                    loadOptions={(inputValue, callback) => {
                        function handleResponse(response) {
                            const { data: { items } } = response;
                            const options = items.map(i => ({ label: i.name, value: i.id }));

                            callback(options);
                        }

                        dispatchAction(companyGetTrucksInit, { resolve: handleResponse, inputValue });
                    }}
                    name={FIELD_NAME}
                    {...props}
                />
            )}
        </AppContext.Consumer>
    );
}

export default SelectCompanyTruck;