How to decide if a component should be controllable by its parent? - javascript

Some of the components in my APP only has the option for the its parent to provide an initial value. But beyond the initial value, the parent cannot control the component's state or value.
Is this bad design?
Is it always the case that a component be controllable by its parent?

One of the key concepts about new React hooks is allows to components has your own state. By the way, i think you should use Context API from React to shared data or state between components, also you should use Redux if you think your app it will growing in the future.
I will wait your feedback.

Related

Best way to pass props down through many components

Let's say that I'm fetching some images from an API in the App component.
Then I want to pass it to the component responsible to rendering images. But this component is not a direct child to the App component. It is the child of a direct child of App component.
Here's how I would pass the images array down to the image component, but I feel like it might not be the best approach.
But what would happen if this hierarchy gets more complex - even just by one more component:
Intuitively, it might not be the best thing.
So, what would be the best way to pass the images array down to the image component, if there are many other children between them?
The problem is usually called Prop Drilling in the React world: https://kentcdodds.com/blog/prop-drilling
A few options:
Passing props may not be that bad. If the app is small, is a very modular -and easy to unit test- option . You can reduce the verbosity by using prop spread: <Comp {...props} /> and by keeping your component interfaces similar. (many people dislike prop spreading as you can unintentionally pass unsupported props, but if you use TypeScript the compiler will catch that).
You can use a React Context: https://reactjs.org/docs/context.html (as other mention in the comments). However, keep an eye on how your context objects are defined (keep them small). React will re-render all the childs using the context when the value changes, is not smart enough to automatically detect changes at the property level. Frameworks like Redux or Zustand use other mechanisms to allow a granular control of the shared state (you'll see examples of a useSelector hook).
You can also take a look to a state management framework (Zustand is my favorite, but Redux is more popular). However, it may be an overkill for small things.
My personal choice is to start with prop drilling, it's easier to modularize and unit test. Then you can think on your app in layers: upper layers depend on a context (or a state framework), and lower layers receive properties. That helps when you want to refactor and move reusable components to other projects.

Can two components have the exact same state, asynchronously updating?

Context:
I am working on a React App, and have two sibling components (NOTE: there is no parent-child component relationship) which both have one identical state. They need to asynchronously update (i.e. When Component1 causes the state to change, then Component2 should have knowledge of that state change and use the changed state as the initial state).
The Problem:
I am using useState(intitialValue) to set the states in each Component, but I am noticing that this is causing my states to go out of sync, as the state depends on modifications done by Component1 or Component2.
(i.e.)
If Component1 caused the state to change from "red" to "green" via some component method, and in Component2 I do:
useState("red")
Then Component2 did not correctly get the information of "green" that was from Component1; instead it received the information of "red" from the initialization of the initial state.
PS:
Please don't simply tell me to pass the state as props. Reminder these are NOT parent-child components!
Any help is greatly appreciated. I think this is a great and common ReactJS issue to solve.
If there is no any relation between two separated components, why they should be synchronous? the substantial question is that, what event do you expect cause to change state in both component? then you can subscribe both components to that event. event can be router change, received data from server asynchronously, browser based events (like resize) or common data changing in memory. some of these events have own hook like route change. But if your event is data change you can use a common service in the both like redux, rxjs or some other state management frameworks. Or if you are pro can write your own hook for your particular event.
If you had shared some sample code, it would help more.

Understanding the props concept in React

While I'm learning React, it's always said that you should keep your state in the parent component and pass them as props to its children.
But in the real world, whenever I start building a react app, I end up passing data from a child component to its parent.
For example, if I have to implement a form somewhere in my react app, I create an extra component for it (for example, FormComponent) and import it in my App component.
But now, I have to pass the form data form the FormComponent to the App component. In other words, from the child component (FormComponent) to the parent (App component).
And this was just an example. Usually, I always end up in situations where I have to pass data from child to parent rather than the other way around.
Do I misunderstand the concept of passing props completely?
If we stay with the above example, is my approach, right?
You can't pass data from child to parent as in React, The Data Flows Down.
So usually you pass callbacks from parent to its children, but the state remains in the parent.
This is commonly called a “top-down” or “unidirectional” data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components “below” them in the tree.
If you in a situation where the code becomes unreadable, unmaintainable, you should consider Lifting the State Up.
Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor.
Aside from it, a common anti-pattern is Prop Drilling, Context API, and many state libraries like Redux, MobX, and Recoil trying to solve such problems with some extra features.
1- In your case you can pass a function ( Example: handleSubmit() ) through props from parent to child.
And so when this function is called the child's data would be hundled from the parent.
you can use this doc page to inspire your code.
2- Otherwise you can use react redux, and then you can hundle all data at any component in your project using one global state called redux store.
want to learn more about react redux click here.
3- Have a nice day ^_^ .

Connecting components to redux global state v.s passing props down to children components in React-Native

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!

Getting to Grips with Component Heirarchy in React

Im learning React and pondering over the structure of the components. The following has me confused a bit.
We are told that there should be a single source of truth.
The owner component should pass the props / states to its responsibility (as some call 'ownee') components.
So, if my own whole app is one big component (owner) with lots of its responsibility (ownee) components, does that mean that that top level owner component will hold ALL the props and states. That would be a massive object.
As Im not initially using states, any changes to props would have to be passed to the 'owner' & then that component rendered again?
Clearly this is not right, right? Any guidance would be much appreciated.
That interpretation is slightly off-mark. Your top level component doesn't need to be an all-knowing omniscient behemoth, simply because of the crucial difference between props and state. Any component is free to pick and control its own state, which it can pass down to its children. However, a prop for a component should not ideally be preserved in its state variable because that's what causes a duplicacy and violates the single source of truth paradigm. A prop is NOT owned by the component, it is owned by the ancestor which sent the prop down. On the contrary, it is natural and expected for a component to pass its state down as props to its children.
You will see that you can't do much without state, unless your app displays static content mostly. So when you start dealing with state, keep state where it belongs. Even with Flux there are ways to keep state relevant to the component to which it belongs.

Categories

Resources