React + Redux + Immutable - how deep should immutable objects go? - reactjs

I have a brand new project using React, Redux, and Immutable. I create my state that is a heavily nested Immutable Map. At what point, if any, should I call toJS on it as I pass it's parts down into the child component's props?
I think it makes sense to keep it always one of the Immutable classes (esp in a new project), and I really like the getIn functionality.
Downside, it's not clear if an object deep inside a presentation component is an Immutable class or a plain JS Object.

I recommend keeping it as an Immutable all the way down.
If you ever call toJS on a piece of your Immutable state prior to passing it as a prop to a child component, you'll lose the benefit of that child component being able to do a simple reference check on that prop in its shouldComponentUpdate. See the advanced performance section of the React docs for more info.
Is there a reason you ever want to call toJS? Ultimately, you're just going to be accessing primitive values for your UI eventually anyway, so it's easy enough to access them with get/getIn. And as a bonus, those Immutable types come with some handy methods.
As for the downside you mention, if you use react-immutable-proptypes it makes it easy to see/enforce what each component expects. And if you make the decision to go Immutable all the way down, there's nothing to remember anyway.

Related

Is it better to pass prop to child even if I can get it from redux inside child?

In my react application, lets say I have some data which is needed by both a parent component and its immediate child. The application uses redux for state management.
Now, in the child component, I can use useSelector and get the sate. But as I already have the information in the parent (in case it matters, I also got using useSelector), I simply pass props to the child like <Child info={someInfo} />. Here is Child is child component and someInfo is the sate information I got using useSelector.
My question is, should I pass props in this case or get the data using useSelector in child component. Moreover, will passing props be faster than instead of reading using useSelector and vice-versa?
Passing data through props makes the component a functional one or at least more functional. Such components are easier to maintain, test and reuse. It also makes it less dependent on future changes in the store structure. But, as it is often in our lives, there are no things as the only one right way. If your project contains many nested components, passing data all the way down through all layers would make code entangled and complicated.
In my practice, I always make UI components (lists, edits, grids, tables, etc.) as pure functional ones and use them inside business-logic-related components which are connected to store and perform side effects.
I think this is maybe a little opinion-based. Getting it from flux store means there is a hard coupling with store lib. If you pass in the prop, you can reuse the component in another, storeless, application. I've encountered this a lot with some of the components I've made and tend towards passing props in. But again, it can make sense in some cases where the component would never see reuse anyway.

When to use stateless and statefull components in ReactJS after Hooks changes?

So, i know the difference between the two but after hooks i'm kinda confused about when i should use stateless and when use statefull.
When i was learning the basics of React i was told that stateless is the "dumb" function and statefull is "smart". And that i should use stateless in simple things, because props are imutable and also use more than statefull. I dont really know the difference with Hooks changes in 16.8.
I know that we can use setState now but i dont understand it totally.
This is a great question, and one that I think people will have trouble with for a while. The way I see it, the term "stateless" has been dropped from regular component verbiage and they are just called "functional components".
The concept of "stateless" is still very important though, because it involves no inner state that does not mimic its props. As you said, they are dumb. Generally, if a component can be stateless, it will be more performant. Components that are rendered in loops with a high count do much better with this type of structure. On the other hand, don't stress too much about performance until you're hitting bottlenecks, which shouldn't happen until you've got thousands (or more) of components rendering at once.
To address hooks- they allow you to "hook" into the state and lifecycle of a component. As you will see in the docs, they do not offer more functionality, but a simpler API. This leads to cleaner code and more reusable custom hooks.
If you are dabbling with hooks, maybe try it on some new components you need to build. I've found it to be fun and simplifies my code considerably.
As a final answer, I would say that the concepts of "stateful" and "stateless" components is the same. Only the API that allows you to utilize state has been changed.
Your 'dumb' components should remaing dumb.
Your 'smart' components, can take advantage of hooks to make them 'dumb' with a hint of smart.
Imagine a component where you have to make it 'smart' because there is a toggle in it.
With the old way, you would create a component that has State.
With hooks, you can create a dumb functional component, that just happens to use the hook useToggle.
This keeps your code simple and concise, while at the same time keeping the same functionality you used to have building smart components.
Hooks are just another means to use state (and other functionality) in a so-called "smart", functional, component. That said, their existence doesn't change the answer to this question (of which, there are many).
One example of an appropriate use of state is when you have a component that will render different output based on some sort of change to the component after the initial render. More specifically, if you have a component that needs to make a network call to fetch some data for display, you could use state to keep track of the initial non-existence of that data and update it when the network call returns using setState.
In my experience, as a general pattern, you should use state for things that change and props for things that don't.
I think, the question is actually simple, when do we use the state hook in react? The answer is, if you write a function component and realize you need to add some state to it, now you can use a state hook inside that existing function component. Previously you had to convert it to a class component.
Then why don't we use the class component from the beginning instead of function component? Because when it was first introduced, the recommended pattern for react developers was to use as many stateless components as possible, in other words as many function component.
And in my personal opinion, the function component is neater and easier to use, maybe even more suitable with the reusable component concept. So then, yeah, now we can expand the use of the function component even more.
Hope it helps

How best to send Immutable.JS list into a stateless React component?

I'm using Redux, Immutable.JS, and React. I want to pass an Immutable.JS list into my stateless React component. This component maps through the list and renders a child per item in the list.
Example:
function Cats(props) {
function Cat(p) {
return <li key={p.id}>p.name</li>;
}
return <ul>{props.cats.map(Cat)</ul>;
}
The {p.id} part breaks, because props.cats is an Immutable.JS list of maps, so I'd have to update my React component to say {p.get('id')} instead.
I'd be okay to do this, but are there better ways for a stateless React component to consume a list without having to know that it's an Immutable.JS list? This usage violates the best practice in the Redux + Immutable.JS + React best practice, "Use Immutable.JS everywhere except your dumb components". 1
I'm certain other people have dealt with this problem and I don't want to reinvent the wheel.
Can relate with your pain, I have documented this here - What are disadvantages to using immutable state in React?.
For Redux
You can use mapStateToProps to convert immutables into normal JS (state.toJSON()). So the dumb (don't like that term) components should be abstracted from the actual structure of your state.
Otherwise
This is an issue anywhere you want abstraction between your state library and your views. One way I have been able to isolate this to some extent is to use (lenses)[https://medium.com/#drboolean/lenses-with-immutable-js-9bda85674780]. If they seem too complicated, you can make a get([key path], source) method and send that in props to your components and use it to fetch the value. This at least provides some abstraction.
You are not wrong.
If using ImmutableJs what you should do is p.get('id') the other way would be something like props.cats.map(elem => <Cat id={elem.get('id')} key={elem.get('id')}/>)
or IMHOP less elegant props.cats.map(elem=>elem.toJs()).map(Cat) but its just different ways of doing the same thing.
Hope it helps

React: What is the performance penalty of calling setState after mutating the state directly in the component?

Since the component's render method is called with each setState*, I was wondering about the performance penalty if I directly modify the state properties, call setState({}) with an empty object, and let the component fully render itself. This has an interesting side effect in the state management: The state in this case used as a mutable object rather than immutable one. Since the component will re-render with the new state values after the setState call, it will reflect the new values in the view. Of course, mutating the state is not recommended by the React team as they suggest the state should be treated as a readonly object, but nevertheless dealing with a mutable object becomes easier to do state management in some cases.
I know this is not the best practice and probably will raise some eyebrows immediately, but I cannot stop and ask for the performance impact or any other potential problems it may cause in a typical application.
Take a look at the following example for a simple demonstration: https://codesandbox.io/s/k5zy9zw8kv
So, please let me know what you think.
Thanks.
* Unless shouldComponentUpdate has been implemented within the component and returning false based on the current state and the nextState value.
PS: My personal opinion, for state management, it is better to use MobX for mid-sized to large scale applications. My question is mostly for relatively small applications. I think both react and redux are making state management unnecessarily complex than it should be. As a developer with OO background I would like to see simpler and more elegant solutions.
This is a terrible idea.
1. Officially unsupported
Direct state mutation is undocumented, unsupported and untested, so the React team can change the behaviour across versions (without testing/documenting it).
2. Breaks lifecycle methods
You break several lifecycle methods such as componentDidUpdate as prevState will not be the state before the mutation, so you give up your option of using these methods should you need them in the future.
3. Keep state shallow instead
dealing with a mutable object becomes easier to do state management
You probably get this feeling when you have deeply nested states, so modifying a nested property (eg. product.quality) requires cloning the whole object (eg. products) first.
It's recommended to keep your states as shallow as possible, both for state change simplicity and easier performance optimisation. Eg. if you state is shallow, declaring it as PureComponent will avoid it calling render when parent component re-renders with no changes to the child component.
In your example, you can move the state to Product instead:
class Product {
state = { quantity: 0 };
...
this.setState(prevState => ({ quantity: prevState.quantity + 1 }));
}

When using redux with immutable-js - do you call toJS() on your selector? Or do you use .get('prop') in the render function?

Right now I'm using reselect to create my selectors to extract data from the store and pass it to the props via connect.
For simplicity, the result of my selectors is always a JS object (calling toJS() at the end of the selector), something like this:
const selector = state => state.get('data').toJS();
Now I'm trying to improve some performance and I realized that shouldComponentUpdate shallow comparison loses the advantages of immutability because of the way I'm returning from my selectors.
On the other hand, using .get('prop') inside my html seems extremely annoying:
<div>{this.props.data.get('prop')}</div>
Especially if I have a case of passing a simple JS object to a child component which is mutable, like this:
<ChildComponent totalItems={10} />
And then there is no consistency when accessing the props (some are mutable and some are immutable).
I thought of creating an helper unwrap function, something like this:
const unwrap = obj => obj && obj.toJS ? obj.toJS() : obj;
But I don't really like this solution.. I don't really like any of those approaches.
What do you use for both clean code & performance?
To pass props to component collect all data under a key as immutable.
<MyComponent propsKey={Immutable.fromJS({someData: {key: "value"}})} />
To use benefits of Immutable you should avoid from use toJS(). It is very costly and you cannot use useful Immutable functions with that. Until you reach "value", you should use Immutable.get(). It is annoying at first but, you can see how it is useful and easy to use, in time. (To get inner keys using getIn() can be less annoying than chain get functions). In this way your code can work more efficient and you do not need to use unwrap function, in your component you guarantee your data under this.props.propsKey always immutable.
You should wrap your presentational components in a simple higher-order component that calls toJS() on any Immutable.js object props passed to it.
This will give you the best balance of keeping the performance benefits of Immutable.js whilst keeping your container components from re-rendering too much, as well as keeping your presentational components dependency-free and therefore easily reusable and testable.
The Redux docs have a good selection of best practises for using Immutable.js, in particular, when not to use .toJS(), why your presentational components should be kept pure and how a "toJS" higher-order component might be defined and used.
Coming back to my question a year and a half later with my own answer:
Always pass the immutable object if possible. If it's not immutable, just pass it as it is.
I decided that performance is much more important than how pretty the code is.
If a value is either immutable or mutable I pass it as it is and never call toJS if I don't have to. I also won't wrap mutable values with fromJS if they're not stored in the redux store.
I just need to be aware inside the child component that some props are immutable and some are not - and it's actually pretty simple because almost always a complex object will be immutable.

Resources