I'm very new to React, just experimenting with it. I'd like to know what are some common patterns, or libraries o built-ins for handling communication among components. For example, I have am input component and a "list" component that updates from the server according to what is in the input controller. Think of an autocomplete box. Since components have presentation logic, What if the two can't be "besides"? They're in different parts of the page and hence two different controllers.
Also, what if I have a login / logout button that works via Ajax? I imagine a lot of different components across the page reacting to the login / logout action reconfiguring themselves accord to a global "logged" state and the data retrieved from the server for the specific user that has logged in.
What is the best way that React "reacts" to those changes? Thanks
You should checkout Flux and Dispatcher.
It's kind of like a pub/sub system but without the problems of a pub/sub system. The advantage is that all events flow in one direction which makes the architecture much simpler and scalable.
If you haven't already, you should checkout Facebook's official React documentation. They have a really thorough tutorial that covers 90% of the scenarios you'll run into, including best practices for component interaction. They're also really good about building from no knowledge on up. Only takes about 20 minutes to go through: https://facebook.github.io/react/tutorial/tutorial.html
As mentioned in another answer, Redux is an amazing library for handling app state and keeping components separate that shouldn't know about each other. Basically, you can have parent and child components, but if you ever have a component with over 2 levels of children, you should consider using Redux (or Flux) to handle state between unrelated components. The problem redux solves is just breaking up those dependencies and still allowing components to have a single source of truth. Their official documentation is also really good: http://redux.js.org/
Related
One of our business problem statement is, we have to create component such that any consumer can use them as a widget and embed in their website. And the thing is we already have those component made with ember.
We're not aware that which stack the consumer website going to have, that could be random. So we thought of converting these ember components to web components.
We did small POC where we were not able to create web component out of ember component using glimmer. But we're facing couple of problems
We're not able to pass objects/arrays to web components with glimmer (we tried using pass it through properties)
Somehow shadow DOM is not working when web component gets rendered
For using simple glimmer component I have followed https://glimmerjs.com/guides/using-glimmer-as-web-components
Gist:
Idea
The idea was to create framework agnostic component, so that it can be used inside different applications flawlessly. The component was already written in emberjs.
Solution
Solution is to write web-component for obvious, but we've our code already written in emberjs add-on. So we decided to migrate add-on project to latest ember, after we migrated add-on components to glimmerjs and converted that glimmerjs component to web-component (using #glimmer/web-component) and use it across.
We took an effort, and made it working. I'm sharing the current solution that we've applied.
As we were facing couple of challenges as I mentioned in my question. I'll answer those points one by one.
For passing object between two component, we're passing it by raising CustomEvent from child-component to parent-component
didInsertElement() {
this.element.dispatchEvent(
new CustomEvent('data-ready', { bubbles: true, detail: this })
);
}
After a research found that, glimmer does not support shadow DOM, they don't have any plan for supporting it yet. And re-analysing the requirement once we thought shadow-dom is good to have feature. We're using CSS specificity (traditional way) to isolate CSS specific to component :p
Though after applying above things we're in good shape. If in case you wanted to have a look at the code. Please check this github repository (initial look)
I have found a serious flaw I think in ReactJS. Although I admit this flaw perhaps might be a flaw in my understanding :) I am trying to build a simple Todo application (using TodoMVC), and when you try to use something like Redux for state managment, you run into very, very hairy issues when trying to process nested JSON, i.e. a database response that typically would include a parent node ("projects"> and then child nodes "todos") related to the parent.
Redux seems to want you to "normalize" the data from the response so it's immuatable. Not to upset anyone, but this seems like the most ridiculous thing in the universe. So, we build a SPA app to process json responses from our data....and then...oh wait, we have to build an ORM on the client to munge all that data into a different format to process it.
If this is the state (sorry no pun intended), of React, Redux and the like, Javascript frameworks should be abandoned. I built something in Rails in like 20 minutes. Of course it's not a SPA, but it was simple to create this MVC structure... not only does it seem extremely difficult, hairy and overly complicated in React, when Redux is added, it gets into the area of absurdity. Perhaps that is why we only see very very simple tutorials with all these tools.... building huge apps with them isn't possible.
So basically, in just trying to code a simple few lines of this example above with react and redux, I was lead to this:
https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape
Can someone prove me wrong? PLEASE. Just a simple codepen showing me you can have a parent "project" component, which you can add "todos" to as children and the ability to make MULTIPLE parent components, with MULTIPLE children without going down the rabbit hole above.
This is a serious flaw in my opinion if this is true. A showstopper.
Your question and understanding are wrong in a few ways.
For context, I'm a Redux maintainer, and I wrote the Redux "Normalizing State Shape" docs page you linked to.
First, you don't need to use Redux if you're using React. In fact, we recommend that most beginners should focus on learning React first, and only try learning Redux once they're comfortable with React.
Second, Redux is independent of React, although they're commonly used together. You can use Redux by itself, or with any UI framework (React, Angular, Vue, Ember, jQuery, vanilla JS, etc).
Third, normalizing is a recommended pattern, but it's not required. Per the docs page you linked, normalizing data has several benefits, but it's fine to keep your data nested if that works better for your application.
Fourth, there's many large complex apps that are written with React and Redux, not just todo examples. See the Apps and Examples list in my Redux addons catalog.
Both the React docs and Redux docs have links to many CodePen / CodeSandbox examples that demonstrate how to use them - see the Main Concepts and Tutorial pages in the React docs, and the Examples page in the Redux docs.
Also, the TodoMVC.com site has several React todo list examples you can look at.
I'd suggest that you take the time to go through the tutorials in the React docs. You may be interested in my suggested resources for learning React and learning Redux, as well as the articles and resources listed in my React/Redux links list.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
React 16.3.0 was released and the Context API is not an experimental feature anymore. Dan Abramov (the creator of Redux) wrote a good comment here about this, but it was 2 years when Context was still an Experimental feature.
My question is, in your opinion/experience when should I use React Context over React Redux and vice versa?
As Context is no longer an experimental feature and you can use Context in your application directly and it is going to be great for passing down data to deeply nested components which what it was designed for.
As Mark Erikson has written in his blog:
If you're only using Redux to avoid passing down props, context could
replace Redux - but then you probably didn't need Redux in the first
place.
Context also doesn't give you anything like the Redux DevTools, the
ability to trace your state updates, middleware to add centralized
application logic, and other powerful capabilities that Redux
enables.
Redux is much more powerful and provides a large number of features that the Context API doesn't provide, also as #danAbramov mentioned
React Redux uses context internally but it doesn’t expose this fact in
the public API. So you should feel much safer using context via React
Redux than directly because if it changes, the burden of updating the
code will be on React Redux and not you.
Its up to Redux to actually update its implementation to adhere with the latest Context API.
The latest Context API can be used for Applications where you would simply be using Redux to pass data between components, however applications which use centralised data and handle API request in Action creators using redux-thunk or redux-saga still would need Redux. Apart from this Redux has other libraries associated with it like redux-persist which allows you to save/store data in localStorage and rehydrate on refresh which is what the Context API still doesn't support.
As #dan_abramov mentioned in his blog You might not need Redux, Redux has useful applications like
Persist state to a local storage and then boot up from it, out of the box.
Pre-fill state on the server, send it to the client in HTML, and boot up from it, out of the box.
Serialize user actions and attach them, together with a state snapshot, to automated bug reports, so that the product developers
can replay them to reproduce the errors.
Pass action objects over the network to implement collaborative environments without dramatic changes to how the code is written.
Maintain an undo history or implement optimistic mutations without dramatic changes to how the code is written.
Travel between the state history in development, and re-evaluate > the current state from the action history when the code changes, ala TDD.
Provide full inspection and control capabilities to the development tooling so that product developers can build custom tools for their apps.
Provide alternative UIs while reusing most of the business logic.
With these many applications its far too soon to say that Redux will be replaced by the new Context API.
If you are using Redux only to avoid passing props down to deeply nested components, then you could replace Redux with the Context API. It is exactly intended for this use case.
On the other hand, if you are using Redux for everything else (having a predictable state container, handling your application's logic outside of your components, centralizing your application's state, using Redux DevTools to track when, where, why, and how your application's state changed, or using plugins such as Redux Form, Redux Saga, Redux Undo, Redux Persist, Redux Logger, etc…), then there is absolutely no reason for you to abandon Redux. The Context API doesn't provide any of this.
And I personally believe that the Redux DevTools extension is an amazing, underestimated debugging tool, which justifies by itself to keep using Redux.
Some references:
Redux Is Not Dead Yet!
You Might Not Need Redux
Do React Hooks Replace Redux?
I prefer using redux with redux-thunk for making API calls (also using Axios) and dispatching the response to reducers. It is clean and easy to understand.
Context API is very specific to the react-redux part on how React components are connected to the store. For this, react-redux is good. But if you want to, since Context is officially supported, you could use the Context API instead of react-redux.
So, the question should be Context API vs react-redux, and not Context API vs redux. Also, the question is slightly opinionated. Since, I am familiar with react-redux and use it in all projects, I will continue to use it. (There is no incentive for me to change).
But if you are learning redux just today, and you have not used it anywhere, it is worth giving Context API a shot and replace react-redux with your custom Context API code. Maybe, it is much cleaner that way.
Personally, it is a question of familiarity. There is no clear reason to choose one over the other because they are equivalent. And internally, react-redux uses Context anyways.
The only reasons to use Redux for me are:
You want a global state object (for various reasons, like debuggability, persistence...)
Your app is or will be big, and should scale to many developers: in such case you probably need a level of indirection (ie an event system): you fire events (in the past) and then people you don't know in your organisation can actually listen to them
You probably don't need the level of indirection for your whole app, so it's fine to mix styles and use local state/context and Redux both at the same time.
If you need to use middleware for various purposes. For example logging actions, error reporting, dispatching other requests depending
on the server’s response, etc.
When data coming from multiple endpoints influence single component/view.
When you want to have greater control over actions in your applications. Redux enables tracking actions and data change, it
greatly simplifies debugging.
If you don’t want server response to directly change the state of your application. Redux adds a layer, where you can decide how, when
and if this data should be applied. The observer pattern. Instead of
creating multiple publishers and subscribers across the whole app, you
just connect components to Redux store.
From: When to use Redux?
I am trying to refactor an application built with js/html/css into a react app. I have moved the front-end html into react components but am having trouble with the js/jquery that controls the actual functionality of the app. What would be a good approach to integrate the old js and jquery into the new application without having to rewrite everything?
You pretty much have to rewrite, I'm afraid - I've been in this exact position before.
The problem you have is that jQuery is about manipulating the DOM directly - the user clicks a button, and then you make some change to the DOM to reflect the new state of the app.
React works very differently - you tell it how to turn internal application into DOM, and it works out how to manipulate the DOM for you. So when the user clicks a button, you update an internally managed state object, and then React handles the DOM changes because it knows how internal state relates to DOM.
They're two completely different ways of writing an app. A good approach:
Break down the existing app into components (buttons, forms, widgets, navigations bars)
Try to figure out which components "talk to" each other and create a hierarchy
Use a library like Redux to manage the internal state rather than using React component state
Good luck!
You CAN use jQuery in React (so long as the component is mounted), but I highly recommend just rewriting it from scratch. I have worked for teams that have loads of jquery mixed in with their React components mainly because they were comfortable with jQuery but apprehensive about React and it just turned into a nightmare.
Follow Duncan's advice about breaking down your app into components, then just write them in React.
Architecturally speaking, a controller does not know about view (usually) and it certainly doesn't know about some other controllers view. Controllers don't know about other controllers either. Sometimes it is necessary for these loosely coupled components to be able to communicate, but best practice is not to tightly couple them together. Is there a messaging framework plugin that allows different components to emit and receive global messages within the app? Is there a better way to handle these kinds of communications?
It wouldn't be too hard to create a pub/sub hub using something like jQuery.Callbacks. However, that is not part of a typical Ember.js app.
When something happens that needs to be communicated beyond the scope of the responsible controller, the pattern is to send the action up to the router, where the current state can handle it. The router/stateManager is the coordinator of the app, and can respond to the action by sending messages to other controllers and/or models, and/or by transitioning to another state.
I tried to diagram this in a talk I gave recently: http://www.lukemelia.com/devblog/archives/2012/08/23/architecting-ember-js-apps/
I'm still new to Ember, but wouldn't Ember Instrumentation be useful in this case? It allows to publish and subscribe to custom events. Great explanation can be seen in this answer.