I'm using react-redux with the components. It passes dispatch as a prop into my top level component, but i'm having trouble accessing it from deeply nested (and some other more complexly mounted) components. What is the best way to access dispatch from any component? Do I need to pass it manually as a prop to every component I'd like to use it in?
You can use connect on components even if they are bellow some already connected components.
If you don't want to use connect everywhere around you can just explicitly import store and dispatch on it: http://redux.js.org/docs/basics/Store.html
Related
I am just curious if there is a way to access the global state in redux from my component without using mapStateToProps.
Thanks.
you can make use of the useSelector hook from the react-redux library to access the store without mapping it to your props.
you can use:
mapDispatchToProps
mergeProps (this one will give you what you want)
options
in the connect function provided by react-redux
In a react component hierarchy one can pass data from the root component to some component inside component tree by passing props. But what is the optimum way of passing data up the hierarchy? I can think of passing methods from the wrapper to the child. Is there any better way of handling data flow in a deep nested components scenario?
I don't think there is something wrong with passing callback functions from parent to child component.
But, in this case:
<parent onSomeEvent={..}>
<first-child onSomeEvent={..}>
<second-child onSomeEvent={..}>
...
When need to pass some data from child component to higher level parent, and you don't want to pass the callback function like above example you may use state management like react-redux, MobX. You can also use react context api and hooks if you don't want to use additional library.
You just have to keep in mind it isn't overkill for your app.
I'm having trouble understanding when I should be passing props down to child components rather connecting those components directly to the state.
There are two ways that components in my project receive props:
1) Connecting a component (child or parent) to the global state of redux. This allows me to specify which parts of the global state my component will receive, but will re-render when a prop changes.
const mapStateToProps = state => ({
error: state.error,
progress: state.scan.progress,
latitude: parseFloat(state.enrollment.latitude),
longitude: parseFloat(state.enrollment.longitude),
});
export default connect(mapStateToProps)(MapViewHome);
2) Passing props down to child components in typical React-Native fashion.
<MapViewHome error={this.props.error} progress={this.props.progress} latitude={this.props.latitude} longitude={this.props.longitude} />
The reason I'm asking this is because I have parent component A which is connected to the state.
Parent component A passes prop x directly to child B which passes the same prop x to child C.
If prop x changes, this will cause components A, B, and C to re render. I could avoid the re rendering of components A and B by connecting child C directly to the state, so that it is the only component effected by the prop change.
But is it good practice to connect small child components to the global state like that? Why not just connect every component to the state?
This is a complex issue that the redux / react community discuss a ton.
You can probably find tons of Medium articles and React / Redux authors that discuss this.
But to give you a high level overview; If it seems like it's a pain to 'drill' props down from CompA -> CompB -> CompC -> CompD, store the data in redux.
If the data only needs to go from CompD -> CompE, you can pass it down as props.
You could store every prop that needs to be shared into redux as well. Just be aware of managing your redux object and try to normalize and manage the giant object.
Ultimately, it is up to you as the developer to make these decisions, as there is no silver bullet for this answer.
The main advantage of using stateless components is reusability. Using your example, a stateless version of MapViewHome could be used to display multiple maps of different lat/lngs on the screen at the same time since you can pass different props to each one. A stateful MapViewHome could only display one since it relies on global state.
So it's really up to you how to want to architect your components. I think it's a good idea to always start with stateless components but if your use case doesn't require reusability then using a stateful component is fine.
Typically, you don't need to use your store when you're capturing form data or if you're simply trying to hide and unhide elements. For example, you might want to have the local state change when you're typing data in a field and then you might use that local state to pass down to a thunk creator that you're dispatching. If you can provide a bit more context about what specifically you are trying to achieve here, I'd be happy to provide more guidance!
is there a reason people always seem to define these functions at the bottom of every component they are needed?
when ever I create a react/redux project I put these in a /mappingFunctions directory and then import them into the files I need them, thus declaring the functions just once. obviously means the functions include more than necessary but it means they are in just one place rather than defining them a million times.
just wondering why this is not the standard?
Each component/container may need to access different set of variables from redux store and different set of actions. So mapStateToProps and mapDispatchToProps are defined individually for all those components that need to interact with Redux store.
Also you don't need to use mapStateToProps, maDispatchToProps for each component. You can have a balance between passing props down or connecting each component to Redux store.
Check Use Connect or pass data as props to children for more details
Because the state and the actions passed to components are generally different
mapStateToProps - this is callback called by Redux when some part of the state is updated. It is used to update map Redux store changes to properties of your component. Each of your components is most probably interested in different parts of Redux store state. Your container components doesn't need to implement this if they don't need to be updated based on Redux store state updates.
maDispatchToProps - this is callback used to create action closures connected to redux via dispatch. This way Redux store is aware of actions triggered by your component and can update its state accordingly. Your container component will use only handful of actions. It can happen that container component doesn't need to connect any actions, so you would not need to implement this.
If you find yourself duplicating same mapStateToProps/maDispatchToProps across various container components, you should probably reuse same container component on various places of your app and remove such code duplication this way.
I'm developing a react.js project and before the main component is rendered, I call a function that returns an object that all components should be able to access. What is the correct way of doing this in react? Currently, I'm just passing it as a prop to the main component and then I suppose I should have to remember to pass it as a prop to all other components. Is there an easier or better way of doing this?
It seems like you are doing something like Redux. Passing the object as props should be okay. You could make a higher-order component that wraps your components and adds access to that global object via props. This is similar to Redux's connect.
As the expectation in React is application-wide concerns ,like a flux/redux/apollo store, are kept in a root provider component’s context and then accessed elsewhere in the component tree via a Higher Order Component or render props. This provides relief from globals and circular dependencies, and makes testing those components easier.
However, if you have non-component code that will need access to configuration values, you may need to use config global and writing components in a way that accepts config values from props.
see: https://github.com/lorenwest/node-config