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!
Related
I'm coding a small library with a simple structure: one parent component can contain multiple components of the same type as direct children. Here is a sample schematic diagram for the app:
By current design, a ChildComponent must address a variety of properties of their parent MainComponent, and I am looking for a good practice that can help achieve that or an alternative of an app structure that will lead to a good practice.
My considerations:
Using Context API. This won't go well with the goal in mind because of the nature of contexts. As per linked documentation:
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.
Passing all required props from MainComponent to ChildComponent. Despite I meet this approach quite often, I don't think it is good because it leads to duplicate code.
The simplest way is with Props, as you already mentioned. If you are passing only one level down it is probably the best option:
https://reactjs.org/docs/components-and-props.html
If you need to pass code to several children and grandchildren, using props will get annoying, that is called "propdrilling". You can avoid it using a Context that will provide to all the components that want to consume it:
https://reactjs.org/docs/context.html
Another alternative for larger applications is Redux. Is has a store and enables your components to interact with the Redux store. The downside is that it requires a lot of boilerplate.
https://react-redux.js.org/
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
I'm working on a large project built with vue. We are using vuex as the state management system but their are some components where I don't need to access their data anywhere else. So, Is it right to store this data in the component data or stick with the convention and store it in a vuex module.
Thanks in advance.
You need to use Vuex store if the data must be accessible by multiple (independent) components. There are several reasons why you shouldn't store everything in Vuex store.
First things first complexity! If you are building a complex Vuex store you can not use effectively as your project grows.
On the other hand if you're filling your store with unnecessary states, all the states will executed in the first load in the initial JS and the more data will increase the payloads and that occurs longer load of the webapp.
So the best thing what you can do it is keep your local states locally until is it possible, und use Vuex when the communication of independent components is needed.
You can keep data with in your components. You can convert your non data sharing components to Functional Components link here.
Vue process functional components faster than normal one. By converting to functional one you will gain some performance boost.
It is totally fine to keep data with in the components if you don't need to access it globally.
When you create more than one Function Components, You must create keys for them too. You can find the whole conversation here. I gave all the details there with code samples as well.
ENJOY CODING....
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.
Say I want to create a little editor for my software that helps me organise people in my company. I will use React & Redux. The editor is a React component (or maybe container?), and it shows me one person at a time. I can edit things about this person, delete fields, etc. and when I am ready I can click a button which will then give me the next person to edit.
Now, I am quite new to React still and can imagine doing this in 2 ways:
Solution 1: Decouple the editor component
Create an Editor Component, which takes an array of all the people in my company. I do have these people saved in the Redux state of my app, but the editor component will not work on my Redux state, but do all changes in its internal state first, and only once I click save will the Editor component commit these changes to my Redux state. This might be a problem, and changes could get lost if somebody doesn't save their edits.
The advantage here is that I have my Editor de-coupled from the rest of my App, and the logic of the Editor will stay in that component.
Solution 2: Connect the Editor Component to Redux
Here, I would connect my Editor component to Redux. So I would not give my component the people array, but direct access to the my Redux store via selectors (for example). I would also not have a deletePerson() function internal to my component, but pass this down as a prop into my component (and it would presumably be a Redux action). This way my component would work directly on state, which I can see as having advantages.
But taking it out of this app and reusing it somewhere else would get more and more difficult, the more complex my component becomes.
Please remember that I am a beginner and that these two solutions are what I came up with as a response to a problem I am facing in my own application. However, I would appreciate if you could help me out here, and explain to me how I should think about problems like this. Is there maybe a third solution I am not mentioning? Or am I misunderstanding a concept?
Personally, I am inclined to go with Solution No. 1, but I also know that the whole idea of Redux is to keep state in one place. What would you advise? Are there performance differences / advantages with one solution?
Your first solution is good but why not use a service when its provided?
You should try to mix up features of Redux React. First, separate your presentational and container components and in one of your container component pass the props directly to redux store on click,etc. Then use redux actions to access the store like deleting,etc. Provide a UI using React presentational components for data entry and pass this data to redux store. Use redux actions when you think they will be useful and not destructure your app.
Go to https://medium.com/#dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 for further details on how to connect presentational and container components.