I've been using react for the past three years and just watched a few talks about ember and glimmer and got interested in glimmer. So excuse my ignorance if the question doesn't make sense.
What will be an equivalent of a global state / context in a glimmer app? What I'm looking for is a #tracked data which can be accessed deep in the component tree without passing it as argument at each level. Think redux without all those ceremonial action/action-creator/reducer.
A single global atom with bunch of functions to immutably modify it and re-actively see the change on the component tree.
Perhaps you are wanting to use services?
https://guides.emberjs.com/release/applications/services/
Services are app level state, and you can use 'injections' to get access to them deep in your component tree, similar to UseContext.
Also, you may be interested in this: https://www.notion.so/Ember-For-React-Developers-WIP-556a5d343cfb4f8dab1f4d631c05c95b (at http://emberatlas.com, in case the page gets renamed)
There is a section on global state / services / contexts
Note:
Glimmer components are not the default component until ember 3.14
Based on your question the answer is no, at least not yet. Glimmer hasn't made it to v1 yet so maybe open an issue for an enhancement on the glimmer github page
you might also want to look into glimmer-redux
Related
Introduction
React is really flexible, it seems that we are not forced to follow a specific architecture when programming interfaces, unlike with other libraries, it is something like coding a plain view. With small web apps, this is cool, but... as soon as your app starts to grow, the speed with which you code will decrease progressively, contrary to if you had defined your architecture from the beginning of the principles.
My Architecture
In my case, I am not using Redux for state management... instead, I am using React Context + React Hooks.
This is my current project structure (serverless app built using firebase):
/app
/components
/Activity
/Authentication
/Profile
/Buttons
/Text
/Inputs
/Giphy
/Messaging
/HOCs
...
/screens
/Activity
/Authentication
/Profile
/Messaging
...
/contexts
/Users
/Content
/Auth
...
/hooks
/auth
/profile
/users
/content
/badges
/i18n
...
/navigation
/Stacks
/Tabs
...
/services
/third-party
/firebase
/api
...
/lib
/theme
/styles
/utils
/functions (backend)
As you can notice, I am using some kind of domain-driven design to structure my project files.
Also, I am separating concerns from screens and components using hooks, and managing complex state (or which need to be synchronized between routes) inside contexts that contains the respective reducers.
This seems to me like some kind of MVC. Where the View is composed by all my React Functional Components, the controller is composed by all my Business and UI hooks, and the data of my Model is contained inside Contexts (or, at least the dynamic data, because of efficient reasons).
As you can see, I have a folder "services" which is just the interface that my business hooks use in order to connect to my server (cloud functions).
Questions
Does this architecture have a name (flux/redux??)? I mean, with the passage of time as a React programmer, mistake after mistake, I have ended up organizing my projects like this, in a "natural" way.
Is it an anti-pattern to split all my components logic with hooks? I mean, all the functional components of my project just contain the event handlers or the JSX to render the UI. I have moved every single block of code to hooks, some of them contain the logic of my business, others simply complex logic related to the graphical interface (animations, ...)
Which advices do you give to me in order to refine my current architecture?
useSelector with React Context? I have implemented some custom hooks that just read and compute derived data from contexts... as I can't use "useSelector", I don't know if this is something typical, because they just consume the necessary contexts (useContext) and then execute some calculations.
Is it Redux really necessary? For a medium-large project, I have handled it well using React Context and with the help of the hooks my code has been quite clean. Do you think that over time, as the project continues to grow, it will be necessary to move to Redux?
Are react hooks the controllers of an application?
Well, not completely sure that this is the right place to put questions like this, but let try to answer, from my point of view, to these points.
Answers
I don't think this specific architecture has a name (like, for example, this one, that has a name https://www.freecodecamp.org/news/scaling-your-redux-app-with-ducks-6115955638be/). In any case the name would not be "Flux" or "Redux" since these names are more related to how data is treated instead of how folders are structured in the project. I don't think there is some strict rule about folder hierarchy to follow to be fully compliant with Flux or Redux patterns. For sure there are best practices and conventions, but they are not mandatory.
To answer this point, let me share this link https://medium.com/#dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 about an article posted by Dan Abramov. I am sharing this article because of the last update made (the article is dated 2015, but there is an important update made in 2019). As you can see seems that you are doing it good since you are putting the core logic in hooks. Just a note about this point: you said "functional components" but I think you were referring to "presentation components", this is an important distinction because "functional component" means that your component is based on a function (instead of a class), "presentation component" instead means that the component does not contain business logic. A "presentation component" can be both class-based or functional and a functional component can contain business logic (class-based component are being replaced by functional ones, but this is another story).
Some advice: be coherent with capitalization and casing (you are mixing uppercase and lowercase, dash-case and camelCase, usually I like to name every file or folder in dash-case, but it depends on you); nut sure if HOCs folder should be here; maybe you can put all the utils (lib, theme, styles and utils itself) in a directory called utils where each util is named property;
About context, and this is a controversial topic, just want to share some considerations taken from docs https://reactjs.org/docs/context.html#before-you-use-context and share my opinion on that. The idea behind context is "Context provides a way to pass data through the component tree without having to pass props down manually at every level", as per documentation subtitle. So, basically, it si something created to avoid "property drilling", as exposed here https://medium.com/swlh/avoid-prop-drilling-with-react-context-a00392ee3d8 for example. This is just a personal point of view but, maybe, is better to introduce Redux for global state management instead of using Context API.
Don't be scared to use Redux. Be scared if, while using Redux, you have tons of duplicated lines of code. In this case you should think about how to abstract your actions and reducers (for example with action creators). If you will be able to generalize stuff like "getting a list of items from your backend", you will realize that your code will not just have less lines of code than a repetitive one, but it is even more readable and coherent. For lists, for example, you may have an action like const getListOfNews = list("NEWS_LIST", "/api/news/"); where list is an action creator like const list = (resource, url) => (params = {}) => dispatch => { // your implementation... };, something similar with reducers.
No, they just "let you use state and other React features without writing a class" as said here https://reactjs.org/docs/hooks-intro.html from docs. It is important to avoid trying to adapt a pattern like MVC to something that was created with different ideas, and this is a general advice. Is like if you are coming from Angular and you try to work in the same way in React. Basically you should work with React, or other libraries/frameworks, without trying to transform them from what they are to what you already know.
I've recently upgraded a React 15 project to use React 16.9. Specifically, I've completely replaced redux with the new Context API, pure functional components, and hooks. With the Context API, we also gain the ability for nested child consumers to obtain the data without having to pass it using props all the way through. However, I noticed that I don't have any component props anywhere as everything is passed via provider/consumer context.
So my question is does the context API make component props obselete?
I find people abuse redux and context. Btw, redux uses context internally.
To be honest, prop still should be your best friend in most of cases. Only when you want to avoid nested prop passing, you could then explore context where a provider is created as a parent, and then all deep down children can receive it as props.
Prop is still the way when children connect to the provider. The only difference is that these props are stored in a sort of "global" space now.
So in short, context doesn't replace prop, it still uses prop.
You have already answered your question. Context API avoids I quote one from react docs :
Context is primarily used when some data needs to be accessible by many components at different nesting levels. Apply it sparingly because it makes component reuse more difficult
There is no other reason. If I want to reuse component or export it that depends context, user has no idea about it. Use cases like logged User, theme, or sone global state like work flow detail for the whole application etc, makes a good use case.
This is React's explanation for use of Context
Context is designed to share data that can be considered “global” for
a tree of React components, such as the current authenticated user,
theme, or preferred language.
While this holds good for React components, is it practical to consider using context to share data between React containers as well? Is there an alternative for Redux or MobX, inbuilt in React?
React Context can be used in place of something like Redux or Flux but you might want to look into using React Context for low-frequency updates (e.g. theme changes, user authentication) but not use it for the general state management of your application.
This is what Sebastian has to say regarding this....who is greatly involved with React development.
My personal summary is that new context is ready to be used for low
frequency unlikely updates (like locale/theme). It’s also good to use
it in the same way as old context was used. I.e. for static values and
then propagate updates through subscriptions. It’s not ready to be
used as a replacement for all Flux-like state propagation. ---
Sebastian Markbage
https://github.com/reduxjs/react-redux/issues/1177
Hope this helps.
We're currently working on a new web mapping solution at our company. So far we decided to build the app using React and OpenLayers 4. Since we want to use the Redux pattern for our architecture there will be one redux store holding the application state.
The problem we face with this stack is as follows:
The map is the central element in our application and its instance needs to be passed to a number of different components. As an example, a tool for drawing features on the map needs a reference to the map instance so that it can add itself to it as an interaction tool.
We discussed how to structure our app to integrate OpenLayers with React in the most reliable way and ended up with two different approaches:
The first approach we discussed is holding a reference to the map object in the application-wide redux store so that it simply can get passed down to any component via the #connect annotation function of react-redux.
While this solution provides an easy access to map we were wondering whether this would be a tractable approach since the store should be kept minimal and the map object never changes throughout the lifecycle of the application.
The second approach considers rendering components like the draw interaction mentioned above as child components of the react map component. The map instance could then be passed down to the children of the map component either directly as a prop or by leveraging reacts context object using the Provider pattern.
However, the react documentation explicitly advises against using context, though we found a number of solutions using this pattern (react-geo, react-leaflet) and also popular libraries like react-redux make use of it.
We therefore thought about using React.Children.map() to clone the child components and then adding map to them as a prop.
I hope the problem we are facing got clear enough. We do not know what would be the better way in terms of react best practices.
What architecture would fit better to the "react way" of designing/managing and application and why?
I'm late to the party here, but six months ago I would have recommended using Context API as Redux was using it. As an alternate solution, I would have simply maintained a global object reference on window.app.cache.
Now, the React Context API is the way to go for this. Hope Saga didn't complicate the project!
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 7 years ago.
Improve this question
I'm familiar with developing client-side applications in AngularJS, but now I'd like to start using ReactJS.
I also have an eye on the ReactNative which I think will revolutionize mobile apps .
What is the way of thinking and how the structure of a React application differs from Angular? What is the biggest difference?
Directives
If you're familiar with Angular, then the way to think about how React works is by imagining using Angular using only directives. React doesn't have any concept of controllers, services, factories or dependency injection. If focuses only on components (directives in Angular terms).
This is also the way that Angular is headed with Angular 2. Angular 2 introduces a concept called components, and removes the notion of directives, controllers and services/factories. Angular 2 still uses DI, but you're not tying your classes to the Angular world (which you do in Angular 1).
Scopes
So Angular uses scopes for data binding, and any template tied to a scope (or a parent scope) can read and print out data from that scope, and even modify that scope. There's no concept of a scope in React, mostly because React doesn't do dirty-checking like Angular, but also because React uses regular Javascript scoping to determine what variables/objects are available to the view. More on that later.
Templating
This is an important difference. In Angular you define your templates in either a different file, or as a Javascript string. In React, you define your view in Javascript or JSX. JSX is an XML/HTML like language extension to Javascript which lets you describe HTML (or native views, like in React Native).
In JSX, you can set property values on elements either as strings like <div className="myClass"> or with a Javascript expression, like this: <div className={myClassVariable}> where myClassVariable is a regular Javascript variable. Anything between { and } in JSX is just plain old Javascript. You can pass an object, a function, a string, etc. And your linter can help you when you try to use an undefined variable in JSX, which is something your linter can't do when you use attributes in Angular templates.
By defining your views in JSX instead of HTML strings, you have the full power of Javascript at your disposal. You don't need something like an Angular scope, because you already have a Javascript scope which determines what you can use in your view. This is the reason that getting good at Angular just makes you good at Angular, whereas getting good at React also makes you a better Javascript programmer.
Data binding/mutation/state
Angular uses scopes to define application state. That scope can be mutated either from a view, a controller or a directive. Scopes inherit from each other, so if you get access to a scope, you can also modify the parent scope. This is one of the reasons that big Angular applications tend to get difficult to manage, because the state of the application can be changed from a lot of places. And watches on those changes which triggers other changes makes it even harder to grasp.
React uses two concepts called props and state. Think of them like regular Javascript functions. State are variables defined in a function, and props are the arguments that are passed to functions.
Variables defined in a function can be changed in that function and they can be passed to other functions as arguments.
But arguments passed to a function should never be changed in the function that received them. They can make a local variable and assign its value to the arguments value and change that local variable. But it should never change the argument directly.
So props are values passed to a component from a parent component. The component receiving props doesn't own them, and don't know where they came from, much like arguments to a function. State on the other hand is owned by the component, and the component can change it in any way it wants much like the local variables.
React knows when state and props of a component change since you have to explicitly call setState when you want to change the state of a component. It knows when props change because you pass props to a component when the parent component renders.
When the state is changed, React re-renders the component (and all of its child components). Note that it only re-renders them to a virtual representation of the components. It then performs a diff on what has changed since the last render, and only the actual changes are applied to the DOM. This is essentially the secret sauce of React. The programming model is to re-render everything everytime something happens, but only doing the minimal amount of work needed.
Where are my controllers!?
Like I said, React doesn't have any concept of a controller, it only focus on components. That said, you often still use a controller/view separation when you use React. You have components (sometimes called view controllers) that handle data fetching and state management, but do very little rendering. Instead, you have a separate component that knows very little about data fetching and a lot about rendering. So the view controller component knows how to fetch data, and it then passes that data on the component that knows how to render it. A simple example is something like this:
var TodoItemsComponent = React.createClass({
getInitialState: function () {
return {
todoItems: null
}
},
componentDidMount: function () {
var self = this;
TodoStore.getAll().then(function (todoItems) {
self.setState({todoItems: todoItems});
});
TodoStore.onChange(function (todoItems) {
self.setState({todoItems: todoItems});
});
},
render: function () {
if (this.state.todoItems) {
return <TodoListComponent todoItems={this.state.todoItems} />;
} else {
return <Spinner />;
}
}
});
var TodoListComponent = React.createClass({
render: function () {
return (
<ul>
{this.props.todoItems.map(function (todo) {
return <li>{todo.text}</li>;
})}
</ul>
);
}
});
In this example, there's two components. One which is only concerned about data fetching, and one which is only concerned about rendering. They're both React components, but they have very different responsibilities. This is the separation that controllers and directives have in Angular, but React doesn't force you into it.
Data binding
Angular uses data binding to keep the view in sync with the view model. React doesn't use data binding at all. You could say that Angular monitors the view model for changes and updates the DOM accordingly, whereas React monitors the JSX you return from your components for changes, and updates the DOM accordingly.
Separation of concerns
A lot of people are skeptical of React because they feel that React doesn't separate concerns in a good way. And JSX is often the target of that argument. They feel like putting markup in your Javascript is mixing concerns about the view and the behaviour. If your used to Angular, you probably don't agree that describing behaviour in your markup is a bad idea (since you do that in Angular as well). An often touted counter argument is that React "separates concerns, not technologies" in that the view (markup) and the behaviour of it are not separate concerns but just traditionally separate technologies (HTML and Javascript). By co-locating the behaviour and the markup, you get quite a few benefits:
It's easy to see if you have unused variables or functions. With Angular, you have to look in the template for expressions, and hunt down all places that have access to that scope to see if there are variables or functions on the scope that aren't used.
A component becomes isolated to one file, and you don't have to switch back and forth between a Javascript file and a template file.
A change to the behaviour often requires a change to the markup, and vice versa. So keeping it inside one file makes it easier to see what changes are needed.
This turned out to be a wall-of-text, so please let me know if there's something I should clarify or expand upon.
ReactJS is all about (reusable) components, which imo can best be compared to Angular's directives.
So I would say, imagine creating an app in AngularJS with only directives :)
I started developing in ReactJS a few weeks ago and at first it was strange (writing template code in your JS, wtf?), but now I got used to it. I recently also started playing with React-Native and it is awesome!
I could list a lot of differences between Angular and React here now, but there are some nice articles written by others on that already, so I recommend you to read those to get a clearer idea.
React.js and How Does It Fit In With Everything Else?
AngularJS vs ReactJS for large web applications
Coming to React from Angular
From angular to react # Reddit
and then there is also awesome-react, a compilation of react libraries, resources, tutorials, articles (you name it, it's there)
Related to your question, this section is probably the most interesting for you:
More articles on the approach of ReactJS and comparisons with other frameworks