I have a problem and I'm recently researching about Clean Architecture. That is:
I know that when I want to use Redux in React I will have to do like this:
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root') )
and then, I use useSelector and useDispatch (hooks) to select data and dispatch an action... in my react components.
But, I see an problem (in my opinion). That is my react application is highly coupled with this state management tool (redux).
So, if in the future, Redux becomes outdated or I don't want to use redux, I want to use Recoil, MobX or new modern state management tools, etc... Or maybe, in my app, I want to use redux combined with others (Recoil,...) to manage my app state. So, I want a loose coupling between react and redux.
But, I see very few people talking about this issue. Or maybe I was searching for the wrong keywords. Or is there something wrong with my way of thinking about 'Separation of concerns' in react and redux.
Can anyone give me a fresh look at this issue?
PS: My English is not good. I hope everyone can get my issue? Thanks a lot.
I had experience with both main React state managers: Redux and Mobx and struggled with the same question.
One possible solution might be to wrap state manager logic with your custom hooks which will receive redux state and trigger actions.
But if you one day decide to switch to, say, Mobx, you will see that:
Mobx reactivity works in a different way than in redux.
First, you will face the necessity to wrap your components in observer function which adds coupling to your components. Besides, it will take some effort to refactor your components to make it Mobx compatible because Mobx reactivity relies on value dereferencing. You can read about it in Mobx documentation. https://mobx.js.org/understanding-reactivity.html
As i see, you can't make your components fully state-manager-agnostic if they rely on business logic.
Anyway, state receiving and state updating logic will be present in your React components and it will take some time and effort to put your project on the new rails.
The only option i see is to split React components into two types:
Container component.
All state-manager logic goes here. It receives application state chunks, triggers actions, and passes props to UI-components.
UI-component
Component that builds DOM-elements. It may have its own state, but mainly render logic is based on component props.
This will allow you to reduce costs from changing state-manager in the future, because you can gradually rewrite your container components without worrying too much about UI.
Related
I'm using React and Typescript to create and manage multiple small components on the same static page which works really well so far. I have a few contexts wrapped in a state provider component like this:
ReactDOM.render(
<StateProvider>
<Reps />
</StateProvider>,
document.getElementById("react-reps")
);
ReactDOM.render(
<StateProvider>
<Script />
</StateProvider>,
document.getElementById("react-script")
);
Even though StateProvider is used in both render methods, each one is a separate instance and has independent state.
I'd like to share some of the state between these components, though as I understand it I may have to manually push updates around rather than relying on React (since the updates will transcend the calls to ReactDom.render) but I still can't figure out if there is a canonical way to achieve this. I've been pushing some state around via events which works well for actions the user takes, but is less great for taking action onload because I don't want to rely on timing for which component loads first.
What's the best way to automatically or manually share some state between these two or more components?
Edit: the comment below for how sharing the store from redux is the kind of thing I want to achieve but I would much rather use the contexts I have right now than introduce redux as a dependency. How could this work with contexts?
Try, Redux and React-redux for state management and transferring data between different components. It is handy and professional. It works a bit differently, but once you get then it is very easy to manage.
Recently I had learnt react-redux, I use it to manage state in my website. But I find some interest in react suspense, but seem like suspense is a feature that killing redux. (Maybe) and might cause problem if using together.
For example, if I want to perform async to change state and update the store. Where should I apply the suspense “feature” and redux store update.
I know my question is a bit confusing but I hope you can understand what I said.
Anyone know how to manage state in react SAP if I want to use react suspense? Is only usecontext is usable?
One way you can use suspense and redux together is by using a Suspense library that integrates with redux like Rest Hooks
Suspense and redux are distinct concepts that can be used independently, or together.
Suspense simplifies asynchronous handling, allowing co-location of data dependencies, which makes components independent from their render location, and thus reusable.
Redux enables one centralized store tree, which can be useful when combining information across desperate concepts in a centralized stream.
Which technique is better for state management in react app?
Actually I want to create a big app where I've to manage my state which technique is optimal for state management context, Redux or react custom hook?
I am personally more inclined towards Redux. But if you are a beginner trying to learn Redux you might have some hard time until you understand it. Once you get it you will also like it. Rather than building your own custom hook, It's better to use Redux as if anything goes wrong/you are struck with something, you have community to support and You can also dispatch async calls using some middleware libs like redux-thunk, etc. You can use Redux with forms as well. I guess if you end building your custom hooks you might end up wasting time, taking care of all these.
Of course, it is better to go ahead with Redux, because it is easier to handle large applications with Redux. It has only a single store, which is basically a javascript object. You can divide the store into many pieces, each piece will be for a particular part of the application. All these pieces will be joined together using the combineReducers function provided by redux.
React is a state management library and with the release of React hooks and massive improvements to React context this method of state management has been drastically simplified.
I think in 99% of the situations we do not need redux and add one layer of complexity to project.
For big scale app maybe redux is better choice. but if you choose React for state management you need good information about some concepts and this concepts is:
Local state vs global state(some component needs local state and putting all of their state in global state leads to a lot of problems)
react context and prop drilling problem and How to use React Context effectively
react hooks especially useReducer and useContext
immutable state
You would always need to ask yourself the question: Do i need an additional library?
Redux is on its decline in popularity, due to improvements on Reacts native state management. There is a reason for that!
If you want to work for a company thats not brand new, there is a chance you have to use redux. I was fortunate enough to convince my team to use our own state management library build only with React.useState under the hood.
If your application state logic is quite simple, meaning: states are mostly local, shared state are mostly between parent-child relationship and different states are not heavily depending on each other, then I recommend only using React useState and useReducer (in case you like to use reducers).
Once your application state is getting complicated, you need to have some sort extra stuff of global state management.
The most important thing you need to know about React.useState is, that the returned setState function is your connection to that components state. Lets assume we can take that function out of the component and use it somewhere else. This way you have a function to update your state from outside of your component.
export let exportedStateSetter;
const Component = () => {
const [state, setState] = useState();
useEffect(() => {
exportedStateSetter = setState;
return () => exportedStateSetter = undefined;
});
return <div>{state}</div>
};
In the example above, you can now import the exportedStateSetter and use it somewhere else to update the state of this Component.
!This is not a best pracitce example, this is a simple visualization.
When you think very critically about this, you will realize that now you know how to set a components state from outside of a component, you know how to set states globally.
I stringly recommend using this approach to either build your own global state library or use some that i have created based on what i explained:
npm install --save react-global-state-hook // simple
npm install --save rx-global // complex
To wrap it up: Dont use Redux, if not required by a job. You can always use Redux conventions, by seperating state into stores, update state with a reducer and actions that interact with the state. For that you can use native React state management, if not only React.useState when used properly. React provides you with everything you need and everything you need to build yourself.
I had the best developer experiences with my own libraries that evolved over time. It forces you to understand state management in general and the framework you are using.
Im open for any feedback on the 2 libraries and if you have any questions regarding state, please feel free to keep posting.
I've just setup my Redux store in React native app.
I moved to initialize React navigation for my project, i though that, as long as i'm using Redux to manage my app state, then the default option is that redux also is taking care of Navigation, and it should be hooked up to Redux, i opened React navigation docs, it says literally:
"Think twice before you consider doing this, there is an incredibly good chance that you do not need to do t his!"
So, is it a good practice to manage navigation with Redux, or just implement basic navigation the normal way (outside Redux) ?
Thanks in advance.
React Navigation manages its own state internally (using its own redux store I think...). There's no real need to connect react-navigation state to your own app's redux store since they expose API to do everything you might need to even without the navigation prop. Also it looks like they're dropping support for redux integration in the next version so beware of deprecation.
This is one of those cases where people may introduce unnecessary complexity and research into the project just to be happy about how "neat" the code runs even when it doesn't offer any real deliverable.
I am experiencing some serious fatigue when I tried wiring up redux with react router vs mobx with react router. I also tried to wire up a top level state with router's render func, but since router do not refresh, that method will fail. My state management requirement is rather simple and I am feeling redux or mobx are overkill. All I really need is a top-level state provider that acts as if just like any other component level state and use callback a way to manipulate it.
Been googling and looking at different solutions for the whole morning, however, I can't find a readily available solution with default react state that can work with react router (v4).
Is there a solution avaible? or its really something not possible to do when it comes to state with react router?
How did you setup Mobx? Maybe you're overthinking it. You can setup a top-level observable object that pretty much mimics the standard component state, but with all benefits of reactive programming.
If you use the <Provider> wrapper component from the mobx-react package that store becomes accessible to all your child components using #inject. In combination with #observer any component that depends on your store will update when you change it.
Check out this code sandbox example I created to showcase this for you:
https://codesandbox.io/s/jzv73o97r5
you can try it with react router v6 it has some optimistic approach to do so