Easy Peasy VS React Redux - javascript

Recently I found this library: https://easy-peasy.vercel.app/
Implemented it, and must say it was quite nice. Why it is not so popular as redux? why people tend to use redux when they can use this? What are the advantages and disadvantages of both?
Also wanted to know how immutability of state is conserved in easy peasy when I can do things like that:
addProduct: action((state, payload) => {
state.productIds.push(payload);
})
clearly it mutates the state.. Maybe it doesn't mutate the actual state?
In general wanted to know if all redux principles are kept, and what are the main differences between the two?

easy-peasy is an abstraction over Redux, and it uses Redux internally to manage state.
Some people would choose to use Redux as they would have complete control over how actions, action creators, reducers etc. are implemented. However users of easy-peasy are given an opinionated way of using Redux, which cuts down drastically on the amount of boilerplate you have to write to work with it.
As for how it enforces immutability in the reducers, whilst the code being written looks like its mutating the data, easy-peasy actually uses Immer "under the hood"; quote from the Immer website:
"The basic idea is that you will apply all your changes to a temporary
draftState, which is a proxy of the currentState. Once all your
mutations are completed, Immer will produce the nextState based on the
mutations to the draft state. This means that you can interact with
your data by simply modifying it while keeping all the benefits of
immutable data."
As is stated on the easy-peasy website, the library allows the extension of the underlying Redux store, which allows you to plug in vanilla Redux middleware/enhancers.

Related

Can you bypass state management for simple objects? (global shared state)

Can you globally instantiate a class and that will be reliable on react-native? i.e.
// logs.ts
const instance = new Instance()
export { instance }
// something.tsx
const Component = () => {
instance.method()
...
}
If method were to increment a property by 1 would that property always have been incremented the number of times method was called throughout the project?
The primary benefit here is simplicity. For example, it's easier to define
class SomeClass {
constructor(properties){}
addProperty(key,value){ this.properties[key] = value }
}
than it is to do the equivalent in redux. Why don't people do the above more often?
Just changing the value on some object will not result in state changes/cause a component to re-render. You still need a state provider to have the state set to. If you want to change the state of that Provider you'll need to run setState (or dispatch and useReducer) which means you'll need to pass the dispatch of that function around to all of its children. As your app grows larger you'll definitely want to/need to useReducer and perhaps even several providers, you'll be re-implementing redux which is only about 200 lines of code anyway. So the question will become why did you re-implement redux which is such a popular library that most people know exactly how to use and there is plenty of documentation for, in favor of your homegrown version of redux which doesn't provide much additional value?
In redux a primary benefit is the tooling like redux-logger, redux-thunk, redux dev tools and time travel and others etc which allows you to replay the changes made or undo them. Sure it is easy to modify an object but using redux allows you to testably and consistently see how an object (the redux state) changes over time and undo them. You can test that action creators return the correct actions. You can separately test that given specific actions the reducer behaves as expected and replay that with mockStore. In short, using redux you get the enterprise version supported by a large community of experts who have helped improve and implement essentially the simple class that you demoed.
Although you can do this, it breaks away from the point of redux. Redux is meant to be a centralized state management store, and therefore, allow components to
access shared state from a single location and analyze shared states, because it comes from one place.
track history and actions taken to get state there
makes maintaining, debugging and collaborating on a codebase
much easier.
Doing the first option, all these benefits are lost.
That said, if you have multiple components in one file, and you want them all to share that same global state (not exporting it), using the class constructor to do so isn't a big deal, as long as the project isn't being worked on by other developers.
However, it would make more sense in that case to make an overall component class, and pass state down, as that is the point of React. Declaring a class outside and trying to manage state in the first way, would be a declarative approach, which is what React doesn't want developers to do (i.e there is a better way, like creating a hierarchy of components). That way, components re-render on a change in value, and no weird bugs arise

When should I use Redux in my react application?

I'm working on a react web app and our company bought an admin dashboard panel to save time. In this panel, they used redux to handle states and all setting parameters stored into redux ...
But really I'm confused about using Redux for each use case!
All of my requests and states are components base and are not global and those are not essential to use in other components of this app!
For example to load games list I've this code :
componentDidMount() {
this.setState({
loading: true
});
http._GET('/game/getAllGames')
.then(response => {
this.setState({
loading: false
});
this.props.dispatch(gamesListAction(response.data.result.games));
});
}
In this case, I use a response and list only on the games-list page. So I think it's not logical I store a response.data into redux and then get all data with connecting and another process...
Or another example, for inserting forms I'll never need to store forms insert or API response because it's inserted and not getting data from API!
I've read about redux but I think redux is not suitable for every app and use case and I should not store single-use responses to redux.
The reduxjs FAQ describes it the best.
In general, use Redux when you have reasonable amounts of data changing over time, you need a single source of truth, and you find that approaches like keeping everything in a top-level React component's state are no longer sufficient.
Redux is nothing but a state mangement tool and you need more compelling reasons to use it:
In your case, firstly:
React's setState will bloat the component overtime with growing requirements and it is much
harder to maintain. Separating out the state management into a reducer
refactors nicely and makes it more readable.
Caching component state, for example if you are using a shopping cart, progressive wizards. There a is lot of to and fro in user interaction which result in state changes, in such cases. Maintaining your state in redux makes a lot of sense now.
Deeply nested components passing on state and lots of props to their children quickly bloat with growing requirements. This is a classic scenario with lot of wrapper components (especially with UI details). A better way would be to refactor and directly connect low level components to redux (transform into a container. Read: presentational-and-container-components)
Application state mapping to multiple container components. For example, if you had your getAllGames loading state to be represented in some progressive-loader-component somewhere out in your app. Using redux will ease your pain sharing data between this components.
Useful when building root level components which can possibly have interactions from everywhere. Like your useraccount component, modal, alerts, loaders.
You will realize, you are writing some boilerplate code with actions and reducers. Though overtime this is much better than reacts state management which can progressively grow complex within stateful components quickly.
Yes, You are right redux is not suitable for every application, as per my knowledge redux or state management is used mainly if you want to show the user previous state instead of empty when some operation is happening
Here is a bit detailed explanation about when to use redux
https://medium.com/#fastphrase/when-to-use-redux-f0aa70b5b1e2
Happy Coding !

tring to reduce the redux boilerplate with some utils

I was wondering if there's something wrong with the approach I'm trying in this link:
https://t.co/WSV81eDwkr
Basically the idea is to modify only the actions file when you add a new action.
on of the Improvement I'm thinking is to recursivle merge the status passed from the actions with the reducer's state.
Let me know
Good thinking. Unfortunately this is an anti-pattern in redux. Actions are supposed to be "pure", stateless, and non-mutating. You are accessing the state directly from an action, which is circumventing the flow of data (oldState => view => action => reducer => newState). Of course the framework is there to help you so if you find that this solution scales well with your project, it could be the way to go.
But to answer your question, it's definitely the wrong approach if you are trying to keep the Redux approach. Another issue I see is that you can't easily serialize actions so it'll likely break time traveling and the redux dev tools if you were to use them.
It's true that there's quite a bit of boilerplate involved in Redux but it's the price to pay to overcome all those CONS you listed with this new approach. Debugging the state of your application is much harder in this scenario.

Isn't Redux just glorified global state?

So I started learning React a week ago and I inevitably got to the problem of state and how components are supposed to communicate with the rest of the app. I searched around and Redux seems to be the flavor of the month. I read through all the documentation and I think it's actually a pretty revolutionary idea. Here are my thoughts on it:
State is generally agreed to be pretty evil and a large source of bugs in programming. Instead of scattering it all throughout your app Redux says why not just have it all concentrated in a global state tree that you have to emit actions to change? Sounds interesting. All programs need state so let's stick it in one impure space and only modify it from within there so bugs are easy to track down. Then we can also declaratively bind individual state pieces to React components and have them auto-redraw and everything is beautiful.
However, I have two questions about this whole design. For one, why does the state tree need to be immutable? Say I don't care about time travel debugging, hot reload, and have already implemented undo/redo in my app. It just seems so cumbersome to have to do this:
case COMPLETE_TODO:
return [
...state.slice(0, action.index),
Object.assign({}, state[action.index], {
completed: true
}),
...state.slice(action.index + 1)
];
Instead of this:
case COMPLETE_TODO:
state[action.index].completed = true;
Not to mention I am making an online whiteboard just to learn and every state change might be as simple as adding a brush stroke to the command list. After a while (hundreds of brush strokes) duplicating this entire array might start becoming extremely expensive and time-consuming.
I'm ok with a global state tree that is independent from the UI that is mutated via actions, but does it really need to be immutable? What's wrong with a simple implementation like this (very rough draft. wrote in 1 minute)?
var store = { items: [] };
export function getState() {
return store;
}
export function addTodo(text) {
store.items.push({ "text": text, "completed", false});
}
export function completeTodo(index) {
store.items[index].completed = true;
}
It's still a global state tree mutated via actions emitted but extremely simple and efficient.
Isn't Redux just glorified global state?
Of course it is. But the same holds for every database you have ever used. It is better to treat Redux as an in-memory database - which your components can reactively depend upon.
Immutability enables checking if any sub-tree has been altered very efficient because it simplifies down to an identity check.
Yes, your implementation is efficient, but the entire virtual dom will have to be re-rendered each time the tree is manipulated somehow.
If you are using React, it will eventually do a diff against the actual dom and perform minimal batch-optimized manipulations, but the full top-down re-rendering is still inefficient.
For an immutable tree, stateless components just have to check if the subtree(s) it depends on, differ in identities compared to previous value(s), and if so - the rendering can be avoided entirely.
Yes it is!!!
Since there is no governance of who is allowed to write a specific property/variable/entry to the store and practically you can dispatch any action from anywhere, the code tends to be harder to maintain and even spaghetti when your code base grows and/or managed by more than one person.
I had the same questions and issues with Redux when I started use it so I have created a library that fix these issue:
It is called Yassi:
Yassi solves the problems you mentioned by define a globally readable and privately writable store. It means that anyone can read a property from the store (such as in Redux but simpler).
However only the owner of the property, meaning the object that declare the property can write/update that property in the store
In addition, Yassi has other perks in it such as zero boilerplate to declare entry in the store by using annotations (use #yassit('someName'))
Update the value of that entry does not require actions/reducers or other such cumbersome code snippets, instead just update the variable like in regular object.

ReactJS: PureRenderMixin addon footnote - contradiction?

from the documentation here: http://facebook.github.io/react/docs/pure-render-mixin.html
The footnote is saying that you should use forceUpdate() if the structure of complexe data (deep data structure) is changed.
From the definition of a pure : it renders the same result given the same props and state.
I'm thinking more and more that this is a contradiction because if the data structure changes, it means that you are giving new props/state. Thus the component is not "pure" anymore.
In my opinion, if you change the props or state that is passed to the component you can either:
use forceUpdate().
remove PureRenderMixin from the mixins.
Thus, under the hood... you are transforming a component that is pure to a "non-pure" component. So removing PureRenderMixin should be the only option available.
Am I right ? Or a Pure component means that the component is "cached" and reused when giving the same props ?
Sorry but I'm a bit confused here.
PureRenderMixin is used to give React a way of knowing that it shouldn't call your render method unnecessarily. For example, if your render method is complex enough, it can give you a performance boost if your component isn't being re-rendered with the same props/state.
But, like it's said in the documentation, PureRenderMixin does not compare deeply nested data structures, so it might not call your render function, when it should have, because some nested structure actually changed.
In these cases, it's better to not use PureRenderMixin and use shouldComponentUpdate and perform you own comparison logic.
Also, from the docs, you should avoid using forceUpdate.
The absence of side effect is an important aspect of the mixin because it enables the logic of not rendering the component twice given the same state.
That shouldn't be a satisfying answer because, as you pointed out, nested changes won't be caught by the shallow checking... Unless your data structure are immutable!
I strongly recommend watching Lee Byron's talk on immutable data structures which explains how immutable data improves the performance of your application by avoiding a whole class of problems.
Essentially, a smart library like immutable.js will share common state between two snapshots of an immutable object.
Therefore shallow equality becomes a proof of the underlying data not being changed.

Categories