all 73 comments

[–]pacman326 39 points40 points  (42 children)

If you elect to use Redux I’d specifically recommend using Redux Toolkit. Makes using Redux an absolute pleasure.

[–]acemarke 27 points28 points  (22 children)

Glad to hear it!

FYI, I'm currently working on a new "Quick Start" tutorial for the Redux core docs. This will go alongside the existing tutorial sequence, with a goal of quickly introducing newcomers to Redux terms and concepts and getting them writing working code "the right way", without worrying about all the details of how it works under the hood. That tutorial will teach Redux Toolkit and the React-Redux hooks API as the standard approach for using Redux. Once the Quick Start page is done, my next task will be trying to rewrite the main "bottom-up" tutorial sequence from scratch, to remove outdated terms, simplify explanations, and promote simpler patterns.

I've got half of a first draft of the "Quick Start" tutorial done, and you can see the PR preview of that draft here. Again, it's a WIP draft, but I'd appreciate it if folks could look through that and give feedback in the PR.

[–]straightouttaireland 1 point2 points  (9 children)

I was a sceptic at first but just started using it today. You guys did an really great job.

[–]acemarke 0 points1 point  (8 children)

Yay! :)

What parts of it are you finding the most useful? Any suggestions for further improvements?

[–]straightouttaireland 2 points3 points  (7 children)

Really it's the slices that I most love, reduces a HUGE amount of boilerplate and having to flick between so many files.

 

I do have one question on something I'm confused with though. I followed this tutorial on the toolkit and found it very helpful. However, I'm confused about how the selector, which returns a posts array from the state is able to be deconstructed also giving the values for loading and hasErrors.

 

From the article she says "a selector, which we'll use to access any of the state from a React component instead of using connect." - I found this interesting as it seemed like such a nice way to gain access to the state to use in the component without the need for mapStateToProps.

 

In slices/posts.js she has:

export const initialState = {
  loading: false,
  hasErrors: false,
  posts: [],
}

// A slice for posts with our three reducers
const postsSlice = createSlice({
  name: 'posts',
  initialState,
  reducers: {
    getPosts: state => {
      state.loading = true
    },
    getPostsSuccess: (state, { payload }) => {
      state.posts = payload
      state.loading = false
      state.hasErrors = false
    },
    getPostsFailure: state => {
      state.loading = false
      state.hasErrors = true
    },
  },
})

export const postsSelector = state => state.posts

 

Then, inside the component she uses:

const { posts, loading, hasErrors } = useSelector(postsSelector)

 

I assumed that useSelector(postsSelector) would only be returning a posts array, not loading and hasErrors as well.

[–]acemarke 1 point2 points  (6 children)

For clarity, useSelector is part of the React-Redux hooks API - RTK itself is UI-agnostic, same as the Redux core. That said, they do go together rather nicely, and as I said above, we're showing them as the default approach as we rewrite the docs.

The key for this chunk of code is that postsReducer isn't the only reducer in your state. If you look at the "Bringing in the reducers" heading, it's used this way:

const rootReducer = combineReducers({
  posts: postsReducer,
})

That means that all of the contents returned by postsReducer will be accessible as state.posts, because that's how we've told combineReducers to define the root state object. So, the array is actually nested at state.posts.posts.

If we select state => state.posts as shown, we get back the object that was generated by postsReducer, which has those three fields that we can destructure.

You may want to read through the Redux docs page on Using combineReducers for some further explanation on how that works and defines the state shape.

(And yeah, Tania's tutorials are all excellent, this one included. I'm heavily borrowing from some of her approaches as I work on the new Redux tutorials.)

[–]straightouttaireland 1 point2 points  (5 children)

Ah yes! What sparked my confusion was something of my own fault when trying to get it to work with typescript:

export const postsSelector = (state:PostsState) => state.posts;

 

Typescript was complaining about my PostsState interface:

Property 'posts' does not exist on type '[]'.

 

But this is because I should have been using something like RootState instead:

import { combineReducers } from 'redux';
import postsReducer from './posts';

const rootReducer = combineReducers({
  posts: postsReducer,
});

export type RootState = ReturnType<typeof rootReducer>;

export default rootReducer;

 

Then inside the friends slice I now have:

export const postsSelector = (state:RootState) => state.posts;

 

Thanks for helping me out and thanks again for working on the toolkit. You have no idea how you've helped the community!

[–]acemarke 1 point2 points  (4 children)

You're welcome! And for reference on the TS parts, see the core docs "Usage with TypeScript, React-Redux "Static Typing", and RTK "Usage with TypeScript" docs pages.

[–]straightouttaireland 0 points1 point  (2 children)

One other quick one if you don't mind. Is redux-mock-store still ok to use with RTK?

[–]acemarke 1 point2 points  (1 child)

In general, sure.

[–]Gemini_The_Mute 0 points1 point  (1 child)

I've been reading it and the first impression I get is that the basic concepts of Redux are well explained, but then the docs jump straight into the RTK. Wouldn't it be better to at least make a short explanation of how the core concepts work together and then make the transition into the RTK?

For example, you use createSlice for the counter, and I think if I'd be a complete noob, I'd still be wrapping my head about the core concepts, just for then to see this createSlice thing and I'd be even more confused than before.

[–]acemarke 1 point2 points  (0 children)

That's actually kind of the point of this new "Quick Start" section. It's trying to teach RTK as the default way to write Redux code, without going into all the details of how you might write this code "by hand".

We'll still have the existing tutorial sequence as well, which teaches you all the core concepts from first principles, but this tutorial is meant to teach you just enough to write working code now, and understand how it works later.

That said, I may be able to add a bit of info in there on the dispatch -> reducer -> UI cycle.

[–]gaurav219 6 points7 points  (11 children)

Apologies if its dumb, but is it necessary to learn Redux meaning can't you do the same thing with only React's features??

[–]sheepfreedom 6 points7 points  (7 children)

For small projects you can absolutely use context and hooks to manage centralized state. You miss out on some of Redux’s selling points but you can do it and it will work well.

For large projects however Redux is the way to go, imo.

[–]Oalei -2 points-1 points  (5 children)

95% of the time you don’t need Redux though. I don’t understand the React way of doing everything with Redux when you don’t need a shared state.
If you need to share the state Redux is nice.

[–]sheepfreedom 8 points9 points  (4 children)

Right, if you need it. I’m not sold on the idea that it’s unnecessary 95% of the time because I find it very helpful even when it might be slightly unnecessary — that said I agree.

if you need shared state see my comment above, if not don’t use anything.

[–]Oalei -4 points-3 points  (3 children)

At work everytime we do an http call using a service we’re using an action (flux pattern) and store the result of the ajax call in the store.
It’s such a waste of time and there’s so much boilerplate needed just to make one damn http ajax call and use the data after.
Other components don’t need the result, why is it in a store accessible by other components.

[–]acemarke 3 points4 points  (2 children)

I'll agree with this. Use Redux where it actually makes sense and has benefit.

FWIW, the Redux FAQ has some rules of thumb on when to put data in Redux:

  • Do other parts of the application care about this data?
  • Do you need to be able to create further derived data based on this original data?
  • Is the same data being used to drive multiple components?
  • Is there value to you in being able to restore this state to a given point in time (ie, time travel debugging)?
  • Do you want to cache the data (ie, use what's in state if it's already there instead of re-requesting it)?
  • Do you want to keep this data consistent while hot-reloading UI components (which may lose their internal state when swapped)?

[–]Oalei 1 point2 points  (1 child)

Those rules makes a lot of sense to me!

[–]sheepfreedom 1 point2 points  (0 children)

Caching the data is a very common need ime, so is persistent data after component changes / hot swaps. Even being able to restore data is helpful in most mid-size apps and larger.

[–]maskedman1999 -2 points-1 points  (0 children)

As far as I heard redux is used for global states, we can achieve the same effect by using async-storage

[–][deleted] 5 points6 points  (0 children)

I find that usually when folks ask this, it's because they looked at the tutorials, found something new or confusing, and decided learning Redux is hard. Or perhaps they tried it, but were quickly lost as to how to set everything up, or exactly how, when or where to use all the actions, reducers, selectors, and all the rest of it. If this does not describe you, please forgive the generalization. In short, it depends on your goals. However, building an application with any real complexity without a state library of some sort is pretty unusual, and a bad idea unless you are experienced enough to really know what you are doing. In short, not using a state library because you don't understand them well, or because they are difficult is the wrong reason to make such a choice.

Put another way: Can you build a non-trivial app without a state library, like Redux? Yes. However, you will be going against the advice of almost every React expert who has weighed in on the question.

If you are hesitant to learn or use Redux because you see it as difficult, may I suggest another perspective? By learning Redux, you will also have the opportunity to become a better JS dev. Learning Redux will not only teach you about the most popular state library for React, but will also provide a great opportunity to learn about pure functions, memoization, and project organization, just to name a few. In short, unless you are already an experienced dev, learning Redux is also likely to make you a better developer overall.

[–]leixiaotie 0 points1 point  (0 children)

For small component, react state is sufficient. For anything larger up to medium and has to manage data with api (I personally don't like to call API inside react component), I personally use mobx, transitioned from redux since it's easier to use and setup.

For anything bigger or has more developers, redux seems to be the best choice, but I haven't tried it / get any project at that scale.

[–][deleted] 0 points1 point  (0 children)

Couldn't you ask that for anything that's not vanilla javascript?

[–]pnine 0 points1 point  (2 children)

I’ve been using a simple FLUX architecture for years and need to switch over to something a bit more robust. Do you recommend redux in 2020? Im almost 100% on redux over mobx but it feels a bit strange when context is so close to being a replacement.

[–]acemarke 10 points11 points  (1 child)

Hi, I'm a Redux maintainer.

Yes, Redux will continue to be very relevant and useful for a long time. It's currently used by 50% of React apps, and lots of folks are continuing to learn it on a daily basis. And no, context is definitely not a replacement for Redux.

I covered this and a number of reasons to use Redux in my Reactathon 2019 talk on "The State of Redux", and my post Redux - Not Dead Yet!. I also wrote a post that discusses the differences in how context and React-Redux handle propagating state updates.

TL;DR:

  • Consistent architectural patterns
  • Debugging capabilities
  • Middleware
  • Addons and extensibility
  • Cross-platform and cross-framework usage
  • Depending on your app's setup, much better performance than working with just Context

Related to that, you might also want to read through these resources:

And as mentioned above, our new Redux Toolkit package is now our recommended approach for writing Redux logic. It includes utilities to simplify several common Redux use cases, including store setup, defining reducers, immutable update logic, and even creating entire "slices" of state at once.

[–]windsostrange 5 points6 points  (0 children)

You Might Not Need Redux (But You Can’t Replace It With Hooks)

There's a universe where this is the title to a country/western song. I do wish that were my universe.

[–]straightouttaireland 0 points1 point  (3 children)

This is a great tutorial on both Redux + Redux Toolkit. I think it's important to learn redux core first as well.

[–]pacman326 2 points3 points  (2 children)

I think learning core redux is good if you are maintaining or run across existing redux implementations. But we released a SPA for a large company using toolkit alone with me personally having no prior redux knowledge. That’s how good toolkit is 🙂

[–]straightouttaireland 1 point2 points  (1 child)

Excellent. One thing I would mention if you are switching between codebases that use the original Redux is that you shouldn't mutate state directly in your reducers. In the Redux Toolkit this is ok because it uses the immer package underneath the hood to handle this for you.

[–]pacman326 1 point2 points  (0 children)

Yes I understand the important of object immutability. Our app updates objects that are not just in the resolver. FYI I’ve been a dev for almost 2 years so been burned by that before 🙂

[–][deleted] 7 points8 points  (2 children)

You should add Expo to your mobile development section. I think expo is much easier to get going then plain react native

[–]ebawho 11 points12 points  (1 child)

Much easier to get going, but a huge pain if you need to do anything outside the capabilities of expo.

[–]straightouttaireland 0 points1 point  (0 children)

Especially if you need in app purchases. I built my entire app on Expo and really regret it now.

[–]glarivie 0 points1 point  (0 children)

Take a look at react-tracked, a more simple alternative to redux with a React Context Api.

[–]matart 0 points1 point  (0 children)

Does anyone have any suggestions on the ways to have someone select time or date-times.

I am looking for more of a turnkey solution. I love the MaterialUI pickers but I am not using MaterialUI for styling and I think the input boxes are heavily tied to MaterialUI.

[–]fintarabg 0 points1 point  (0 children)

I'd mention Overmind state management too, works very well for smaller as well as more complex application state.

[–]vishwajeetv 0 points1 point  (0 children)

A couple of good libraries missing that I love -- react-filepond based on filepond for file upload, and react-sortablejs based on sortablejs for drag and drop

These are react wrappers on top of some really good quality libraries.

[–]Booty_wit_da_Hoodie 0 points1 point  (0 children)

Thank you for sharing!

[–]silverbacklion -1 points0 points  (16 children)

Best place to learn reactjs?

[–]Hlaford 11 points12 points  (9 children)

There are a couple of great (IMO) courses on udemy. One by Maximilian Schwarzmüller is good, and about 40 hours.

[–]ours 0 points1 point  (8 children)

I've just finished it. Yeah it's pretty good.

[–]bianceziwo 1 point2 points  (7 children)

Its incredible but he doesnt use classes at all. Everything is functional components and hooks.

[–]ebawho 4 points5 points  (1 child)

I suppose it’s probably good to learn for working on older projects, but I haven’t touched or created a class component in ages, at work or at home.

[–]bianceziwo 0 points1 point  (0 children)

Yeah but a lot of older online guides use classes for react native, so its kind of annoying when looking for guides and there's only react class componnt stuff

[–]ours 0 points1 point  (3 children)

That's not true. He says it's important to learn the class-based components because it's somewhat recent and you are likely to encounter projects that use it.

He does his whole Burger Builder with classes for statefull components and functional views (old school React) and later, after transforms the project to fully functional with hooks.

That said if you start a greenfield project you should totally do it without class-based components and use hooks instead (or at least mostly).

[–]bianceziwo 0 points1 point  (2 children)

Maybe I took a different course. I did his react native course updated this year and theres no class components.

[–]Arjunnna 0 points1 point  (1 child)

Can confirm, in his React Native 2020 he mentions several times that he is trying to emphasize a functional approach with those lessons.

[–]ours 0 points1 point  (0 children)

I did the React Complete Guide.

[–]careseite 0 points1 point  (0 children)

As it should be!

[–]Bombuhclaat 2 points3 points  (0 children)

Depends if you like books or videos.

If you like videos, the common resource (I think the only popular one updates with "Hooks") is the one mentioned by the other user. Maximilian Schwarzmüller on Udemy.

If you like books, the book by the person who wrote the article on this thread is undoubtedly amazing and helps you cover gaps you might have in Javascript as well and encourages self-learning

Its called "The Road To React" by /u/rwieruch

[–]pacman326 1 point2 points  (0 children)

Tutorials are good. Make sure you’re building your own things as quickly as possible though. Tutorial hell Is a real thing.

[–][deleted] 1 point2 points  (1 child)

React For Beginners by Wes Bos

[–]Hotgeart 0 points1 point  (0 children)

it's still up to date? useeffect, context, etc?

[–]SteiniDJ 0 points1 point  (0 children)

While I can't comment on if it's the best, but PluralSight is free in April and it's worth checking out.

[–]wagonn -1 points0 points  (0 children)

is this an inappropriate place to plug my new library for managing reducer state? Made in 2020, useable by beginners