I have file which exports various utility functions to use across components, and these functions needs to access redux state. How do I import the state object to this file?
connect does not work here if your utility functions are not react elements.
Best idea is, import create store and then use getState function,
import store from 'store/createStore';
const state = store.getState();
Well, this isn't a simple answer, but after researching this for too long, I found these, which are the only 2 articles that explain anything. They explain how to access the store directly outside of a Component (if you must) and also mention the pure functions / functional programming philosophy as well as potential performance issues with connecting a bunch of non-component functions to the store directly. Personally, I went with #anoop and passed the params around in a single object as deeply as needed.
For connecting directly (which gets the store from this.context the way connect() does, see the discussion here
and specifically gaearon's comment on Sep 16, 2015 and Sep 22, 2015.
It seems this access can be achieved via connect()
For a little reading on functional programming / pure functions, see the discussion here
The utility should get the state as an argument.
Because you want to use the utility in the components (views) you can store the state in a member variable on your smart component (the one using connect() function) via mapStateToProps(state) callback.
then you can pass this member to your dumb components.
Related
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
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.
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!
I have problem with sharing objects that were created within some component. I am curious how can i access those objects in another component. Can i create a global variable that is accessible within all classes? Unfortunately, i cannot find any relative answers or project in the web.
Create a closure within the component that will hold all the data you want to make available to other components, then export it alongside your component.
whenever you want to use that shared data, require the closure the same way you require a component.
ps: probably it's better to use any variant of Flux, I recommend Redux
Well if you wanna give a children some of the parent object you can do
in the parent:
<Children anything={yourObject} />
and access to yourObject in the children using:
const childrenObject = this.props.anything
But this will work in a simple react app, If you are planning to do something more complicated then you should try to learn redux, it will give your app a global state called Store where you will put whatever you want and access anywhere in your app
https://www.codementor.io/mz026/getting-started-with-react-redux-an-intro-8r6kurcxf
What's the difference between require()ing a singleton, and passing it down via React prop or context?
What are the use cases for each?
If you require() (or import) a module, you get the same object in any component.
Use modules for the code your component depends on:
Other components (Button).
Utility functions (getTextColor).
Global data storage (CommentStore).
The upside of importing a module is that it’s extremely easy to do, and you only need to do it once.
The downside of importing a module is that you can’t override what it points to. So, for example, you can’t easily swap out CommentStore or getTextColor modules in testing, or in a “living design guide”. Depending on your use case, this may or may not be a problem.
Passing something as a prop means you can pass a different thing every time.
Use props for inputs to your components that need to be customizable:
Data (comment).
Event callbacks (onClick).
UI properties (color).
The upside of using props is that they’re explicit and customizable. They’re primary mechanism of passing data down in React so when in doubt, use props.
The downside of using props is that sometimes you might end up passing a lot of props through intermediate components that don’t use them, just to get props down to the leafs. Normally this is fine in React because it trades some verbosity for ease of finding bugs. But in some cases it can get frustrating.
Context is an advanced API and should be used very sparingly.
It is likely that it will significantly change in the future.
Context is like implicitly passed props that become “global” for a subtree:
Theming (currentTheme).
Locale (currentLanguage).
Dependency injection (store).
The advantage over props is that you don’t need to pass them manually through every component. The advantage over importing is that you can override it from outside the component, which is handy for testing, server rendering, and for things that change.
The downside of context is that it has severe issues with updates, so don’t rely on its value updating correctly. For example, React Redux can safely pass store down because store itself never changes and has its own subscription mechanism.
In general we don’t suggest using context in your application code directly. It’s fine if some libraries use it because they will be easier to migrate when its API changes.
Finally, I’m not a natural painter, but here’s a doodle to sum it up: