将异步反应选择与redux saga一起使用

将异步反应选择与redux saga一起使用,redux,redux-saga,react-select,Redux,Redux Saga,React Select,我尝试实现一个异步react select()。问题是,我们想在redux传奇中进行提取。因此,如果用户键入某个内容,则应触发获取操作。然后,Saga获取记录并将其保存到存储中。到目前为止,这是可行的。 不幸的是,loadOptions必须返回一个承诺,否则应该调用回调。由于新检索到的选项会随着属性的变化而传播,因此我认为没有办法将Select.Async与saga一起使用来执行异步获取调用。有什么建议吗 <Select.Async multi={false} value={

我尝试实现一个异步react select()。问题是,我们想在redux传奇中进行提取。因此,如果用户键入某个内容,则应触发获取操作。然后,Saga获取记录并将其保存到存储中。到目前为止,这是可行的。 不幸的是,loadOptions必须返回一个承诺,否则应该调用回调。由于新检索到的选项会随着属性的变化而传播,因此我认为没有办法将Select.Async与saga一起使用来执行异步获取调用。有什么建议吗

 <Select.Async
   multi={false}
   value={this.props.value}
   onChange={this.onChange}
   loadOptions={(searchTerm) =>  this.props.options.load(searchTerm)}
  />
this.props.options.load(searchTerm)}
/>
我有一个错误,我将回调分配给一个类变量,并在componentWillReceiveProps上解析它。这种方式很难看,不能正常工作,所以我寻找更好的解决方案


感谢

redux saga
用于处理副作用,如异步接收
反应选择
的选项。这就是为什么您应该将异步内容留给
redux saga
。我从未使用过
react select
,但只要看一下文档,我就会这样解决:

您的组件变得非常简单。只需从redux商店获取
选项
<代码>选项请求的是请求的选项的操作创建者操作:

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)
换句话说:使您的组件尽可能纯净,并处理
redux saga


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

主要思想是您能够使用应用程序上下文从

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;
从“React”导入React;
从'react redux'导入{connect};
从“@components/Control/Form/Skin/Default/Select”导入Select;
从'@helpers/form'导入{reduxGetter,reduxSetter,required as req};
从“@reduxations/company”导入{companyGetTrucksInit}”;
从“@app/AppContext”导入AppContext;
常量字段_NAME=‘卡车’;
export const getReduxValue=reduxGetter(字段名称);
export const setReduxValue=reduxSetter(字段名称);
const SelectCompanyTruck=(道具)=>{
常数{
必修的,
验证=[]
}=道具;
常量vRules=[…验证];
如果(需要)
推送阀(要求);
返回(
{({dispatchAction})=>(
{
功能句柄响应(响应){
const{data:{items}}=响应;
const options=items.map(i=>({label:i.name,value:i.id}));
回调(选项);
}
dispatchAction(companyGetTrucksInit,{resolve:HandlerResponse,inputValue});
}}
名称={FIELD_name}
{…道具}
/>
)}
);
}
导出默认选择公司卡车;

谢谢您的回答!是的,我想完全按照你描述的那样解决这个问题。关键是,react select的“onChange”(loadOptions),在这里我必须调用“optionrequest”,期望返回一个承诺。那是因为他们希望你打电话到那里。据我所知,没有办法用saga解决组件中的承诺?嗨,我在这里查看了文档:
onChange
不必返回承诺。它只是一个事件处理程序。在我的示例中,我使用
onChange
调用
选项request
操作创建者,然后由redux调度,并最终由发出服务请求的
saga
处理。嘿。哦,对不起,我现在看到混乱了。我不想在我的传奇中使用select as searchTerm的值。React select允许您键入以进行搜索。在这个搜索中,我想为我的react select获取新选项,供用户选择。这是因为可能有数千条记录,我不想一开始就全部加载。这可以通过loadOptions实现,我需要一个承诺。嗨,我也很困惑。再次阅读文档,而不是
onChange
,我的意思是
onInputChange
。我相应地更新了我的答案。好吧,这有点滥用onInputChange。但如果我使用onInputChange并选择组件(而不是Select.Async),它可以与saga一起工作!谢谢你的回答!
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;