使用 async react-select 和 redux-saga
Use async react-select with redux-saga
我尝试实现异步反应-select (Select.Async)。问题是,我们想在 redux-saga 中进行抓取。因此,如果用户键入内容,则应触发获取操作。然后 Saga 获取记录并将它们保存到存储中。到目前为止这有效。
不幸的是,loadOptions 必须 return 承诺或应调用回调。由于新检索的选项随着 属性 的变化而传播,我认为无法将 Select.Async 与 saga 一起使用来执行异步获取调用。有什么建议吗?
<Select.Async
multi={false}
value={this.props.value}
onChange={this.onChange}
loadOptions={(searchTerm) => this.props.options.load(searchTerm)}
/>
我有一个 hack,我将回调分配给 class 变量并在 componentWillReceiveProps 上解析它。那种方式很丑而且不能正常工作所以我正在寻找更好的解决方案。
谢谢
redux-saga
用于处理副作用,例如 react-select
的异步接收选项。这就是为什么您应该将异步内容留给 redux-saga
。我从来没有使用过 react-select
但通过查看文档我会这样解决它:
您的组件变得非常简单。只需从您的 redux 存储中获取 value
和 options
。 optionsRequested
是 OPTIONS_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)
saga 定义监视由 onInputChange
触发的 OPTIONS_REQUESTED
操作,从服务器加载给定 searchTerm
的数据并调度 OPTIONS_RECEIVED
操作以更新 redux 存储.
function* watchLoadOptions(searchTerm) {
const options = yield call(api.getOptions, searchTerm)
yield put(optionsReceived(options))
}
换句话说:使您的组件尽可能纯净,并处理 redux-saga
中的所有 side-effect/async 调用
希望这个回答对你有用。
主要思想是您能够使用来自
的应用程序上下文调度 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;
我尝试实现异步反应-select (Select.Async)。问题是,我们想在 redux-saga 中进行抓取。因此,如果用户键入内容,则应触发获取操作。然后 Saga 获取记录并将它们保存到存储中。到目前为止这有效。 不幸的是,loadOptions 必须 return 承诺或应调用回调。由于新检索的选项随着 属性 的变化而传播,我认为无法将 Select.Async 与 saga 一起使用来执行异步获取调用。有什么建议吗?
<Select.Async
multi={false}
value={this.props.value}
onChange={this.onChange}
loadOptions={(searchTerm) => this.props.options.load(searchTerm)}
/>
我有一个 hack,我将回调分配给 class 变量并在 componentWillReceiveProps 上解析它。那种方式很丑而且不能正常工作所以我正在寻找更好的解决方案。
谢谢
redux-saga
用于处理副作用,例如 react-select
的异步接收选项。这就是为什么您应该将异步内容留给 redux-saga
。我从来没有使用过 react-select
但通过查看文档我会这样解决它:
您的组件变得非常简单。只需从您的 redux 存储中获取 value
和 options
。 optionsRequested
是 OPTIONS_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)
saga 定义监视由 onInputChange
触发的 OPTIONS_REQUESTED
操作,从服务器加载给定 searchTerm
的数据并调度 OPTIONS_RECEIVED
操作以更新 redux 存储.
function* watchLoadOptions(searchTerm) {
const options = yield call(api.getOptions, searchTerm)
yield put(optionsReceived(options))
}
换句话说:使您的组件尽可能纯净,并处理 redux-saga
希望这个回答对你有用。
主要思想是您能够使用来自
的应用程序上下文调度 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;