Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to handle computed properties with Redux?

when using Redux, the store is supposed to be the single source of truth, and to have no redundancy. Suppose part of the store represents people, who have a name and an age. A person class in traditional object-oriented programming might look something like this:

class Person {
    constructor(first, last, birthday) {
        this.first = first;
        this.last = last;
        this.birthday = birthday;
    get_fullname() { // ... //}
    get_age() { // ... //}
}

However, methods aren't allowed on objects in the Redux store. So, where should these "methods" be implemented?

like image 294
Josh Avatar asked Nov 13 '16 18:11

Josh


People also ask

How does Redux work?

Every Redux app has state values, creates actions to describe what happened, and uses reducer functions to calculate new state values based on the previous state and an action. Here's the contents of our app so far: What's Next? We now have some reducer logic that will update our state, but those reducers won't do anything by themselves.

How many reducer functions are there in Redux?

A Redux app really only has one reducer function: the "root reducer" function that you will pass to createStore later on. That one root reducer function is responsible for handling all of the actions that are dispatched, and calculating what the entire new state result should be every time.

Do I need to keep all state in Redux?

This example is small enough so far that we actually do have all our state in the Redux store, but as we'll see later, some data really doesn't need to be kept in Redux (like "is this dropdown open?" or "current value of a form input"). Actions are plain JavaScript objects that have a type field.

What is the root value of a redux state?

The root Redux state value is almost always a plain JS object, with other data nested inside of it. Based on this information, we should now be able to describe the kinds of values we need to have inside our Redux state: First, we need an array of todo item objects.


2 Answers

You can compute this kind of state on-demand inside your connect functions with a selector.

function getFullName(state) {
  return `${state.first} ${state.last}`;
}

function mapStateToProps(state) {
  return {
    fullName: getFullName(state)
  };
}

connect(mapStateToProps)(MyComponent);

Check out Reselect, a selector library that is designed to work well with Redux.

Technically there's no rule saying that you can't handle it in your reducer, then store the precomputed state inside your store, but you'll have to remember to update it each and every time the dependent properties change.

Generally you'll end up with simpler code if you keep redundant data out of your store and using selectors allows you to write and share the on-demand computations between your components as and when you need them.

like image 170
Dan Prince Avatar answered Sep 26 '22 01:09

Dan Prince


There are two ways:

  1. In reducers.

    Not sure where you got the 'no redundancy in the store' rule. It is perfectly valid to have the results of computations to be kept alongside source data in the store (albeit in such simple case as concatenating name and surname that might not be the best approach)

  2. In selectors.

    Selectors are functions used to fetch specific subbranches from the store. They can also perform computations on them before returning. See this chapter in redux' documentation for some examples.

    This, with some memoization where needed, is I suppose the better solution of the two.

like image 33
Mchl Avatar answered Sep 26 '22 01:09

Mchl