Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use async react-select with redux-saga

I try to implement a async react-select (Select.Async). The problem is, we want to do the fetch in redux-saga. So if a user types something, the fetch-action should be triggered. Saga then fetches the record and saved them to the store. This works so far. Unfortunately loadOptions has to return a promise or the callback should be called. Since the newly retrieved options get propagated with a changing property, I see no way to use Select.Async together with saga to do the async fetch call. Any suggestions?

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

I had a hack where i assigned the callback to a class variable and resolve it on componentWillReceiveProps. That way ugly and did not work properly so i look for a better solution.

Thanks

like image 260
MethodenMann Avatar asked Mar 28 '17 14:03

MethodenMann


People also ask

Is Redux saga obsolete?

Such a powerful & elegant tool as Redux-Saga, a Redux side effect manager, is said to be deprecated, and no longer being maintained, starting from Jan 27, 2021.

Is Redux saga async?

redux-saga is a library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage, more efficient to execute, easy to test, and better at handling failures.

How do you use the fork in Redux saga?

Attached forks (using fork )​ The fetchAll body itself terminates, this means all 3 effects are performed. Since fork effects are non blocking, the task will block on delay(1000) The 2 forked tasks terminate, i.e. after fetching the required resources and putting the corresponding receiveData actions.


1 Answers

redux-saga is for handling side effects like asynchronously receiving options for react-select. That's why you should leave the async stuff to redux-saga. I have never used react-select but by just looking at the documentation I would solve it this way:

Your component gets very simple. Just get value and options from your redux store. optionsRequested is an action creator for the OPTIONS_REQUESTED action:

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)

A saga definition watches for OPTIONS_REQUESTED action that is trigged by onInputChange, loads the data with given searchTerm from server and dispatches OPTIONS_RECEIVED action to update redux store.

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

In other words: Make your Component as pure as possible and handle all side-effect/async calls in redux-saga

I hope this answer was useful for you.

like image 151
Alex Avatar answered Sep 25 '22 10:09

Alex