5 ms·
I don't think redux-thunk is the simplest solution. There's really no need to add anything to redux to support asynchronous code. You can just pass the dispatch
by bfrydl 8y ago
I don't think redux-thunk is the simplest solution. There's really no need to add anything to redux to support asynchronous code. You can just pass the dispatch function around.
For example:
async function getArticle(id, dispatch) {
try {
const res = await fetch(`/articles/${id}`);
const text = await res.text();
dispatch({ type: 'GET_ARTICLE_SUCCESS', id, text });
} catch (err) {
dispatch({ type: 'GET_ARTICLE_FAILURE', id, err });
}
}
In my opinion all this middleware business (thunk, saga, etc.) is trying to make redux do jobs it isn't supposed to be doing.
- acemarke 8y agoYes, it's true you can do that. However, it's not what we recommend. I specifically addressed the reasons why we recommend using middleware in the "Side Effects" section of my "Redux Fundamentals" workshop slides [0] [1]. The Redux FAQ entry on "Why do we need things like middleware for async behavior?" [2] also addresses this. In particular, I recommend reading Dan Abramov's answers on Stack Overflow on this top [3] [4] As always, it's up to you how you choose to write your code, but there's plenty of good reasons why middleware is our recommended approach. [0] https://blog.isquaredsoftware.com/2018/06/redux-fundamentals-workshop-slides/ https://blog.isquaredsoftware.com/2018/06/redux-fundamentals... [1] https://blog.isquaredsoftware.com/presentations/workshops/redux-fundamentals/side-effects.html#/4 https://blog.isquaredsoftware.com/presentations/workshops/re... [2] https://redux.js.org/faq/actions#how-can-i-represent-side-effects-such-as-ajax-calls-why-do-we-need-things-like-action-creators-thunks-and-middleware-to-do-async-behavior https://redux.js.org/faq/actions#how-can-i-represent-side-ef... [3] http://stackoverflow.com/questions/34570758/why-do-we-need-middleware-for-async-flow-in-redux http://stackoverflow.com/questions/34570758/why-do-we-need-m... [4] http://stackoverflow.com/questions/35411423/how-to-dispatch-a-redux-action-with-a-timeout/35415559 http://stackoverflow.com/questions/35411423/how-to-dispatch-...
- bfrydl 8y agoYes, I'm familiar with the arguments against it, but my experience using Redux has led me to strongly disagree with them. I don't think the proposed benefits have much value in actual practice, and limiting the use of dispatch to plain objects makes state logic easier to understand in my opinion. Also, I think my primary issue with redux-thunk isn't that you dispatch a non-object but that the getState argument encourages async operations which are dependent on the current store state, possibly its current state at multiple different points of time. Personally I think that as much as possible async operations should be written to use only parameters as input and dispatch actions as output. Plus I use TypeScript where things like this getState argument are really annoying for strong typing. You need to import the type of your store or store state in every file that uses a thunk. I also personally think that the extra ceremony applied to Redux is a contributor to the difficulty new developers have understanding it, because they believe that Redux does more than it actually does.
- acemarke 8y agoI understand most of your concerns, and it seems like we'll have to agree to disagree to some extent. FWIW, I specifically addressed several concerns regarding use of `getState` in my post "Idiomatic Redux: Thoughts on Thunks, Sagas, Abstraction, and Reusability" [0]. I agree that trying to fully capture the potentially dynamic behavior with static types can be painfully difficult. I don't actually use TS myself, yet, but we've definitely had lots of issues pop up related to this (such as [1] ), and I think I get the general issues involved. Unfortunately, I don't have any real suggestions to offer on this front, both because my TS knowledge is limited to "declare types for function params and object fields", and because I'm not sure there _are_ ways around that. Having said that, our new Redux Starter Kit package [2] is specifically intended to help simplify a number of common Redux use cases, and I'd encourage anyone using Redux to try it out. Long-term, we plan to revamp the Redux docs content [3], and I hope to improve a lot of the teaching workflow. I also hope to make RSK the "default" way to use Redux for most people. [0] https://blog.isquaredsoftware.com/2017/01/idiomatic-redux-thoughts-on-thunks-sagas-abstraction-and-reusability/ https://blog.isquaredsoftware.com/2017/01/idiomatic-redux-th... [1] https://github.com/reduxjs/redux-thunk/issues/231 https://github.com/reduxjs/redux-thunk/issues/231 [2] https://redux-starter-kit.js.org https://redux-starter-kit.js.org [3] https://github.com/reduxjs/redux/issues/3313 https://github.com/reduxjs/redux/issues/3313
- bfrydl 8y agoI do think we need to agree to disagree. That being said according to the README for the Redux Starter Kit these are listed as problems it wants to solve: • "Configuring a Redux store is too complicated" • "I have to add a lot of packages to get Redux to do anything useful" • "Redux requires too much boilerplate code" I can't help but point out that all of these concerns can also be solved by not using any extra libraries and just doing what I suggested. Configuration: createStore() Lot of packages: Not needed, just pass dispatch around. Boilerplate code: Pretty much just combineReducers calls.
- acemarke 8y agoI'd encourage you to read through the RSK docs further to see what all it actually does, then :)
- tracker1 8y agoWhat you're describing isn't much different than the use of thunks generally... export const getArticle => event => async (dispatch, getState) => { const id = event.target.dataset.id; ...same as yours... } ... <button data-id={record.id} onClick={this.props.getArticle} ... The main difference is this works out of the box with connect, and can often be bound directly against a given event handler.
- deleted 8y ago[deleted]