What is the difference between the two approaches ?
Passing text for a button as props
<TextComponent title="Save"/>
function TextComponent(props){
return <button>{props.title}<button/>
}
vs
Passing text as a child
<TextComponent>Save<TextComponent />
function TextComponent(props){
return <button>{props.children}<button/>
}
children prop is something that you use when the structure of what needs to be rendered within the child component is not fixed and is controlled by the component which renders it.
However if behaviour of the component is consistent across all its renders it can define the specific props that it needs and the parent can pass them to it.
A very simple example could be a Navbar which can use children. For a Navbar the items that it needs to render as well as the order or alignment or items depends on how it needs to be used at different instances or across different pages. For instance Navbar somewhere can have Search component at one place and at some other place not have it. Also the menus may sometimes be needed to the left followed by Login menu item to the right and a searchbar between them and sometimes they may all be present to the right without the searchbar. In such cases the parent component can control how the internal structure would be
You should use children when you don't know them ahead of time, see: https://reactjs.org/docs/composition-vs-inheritance.html
Here, if you KNOW that you'll use a title inside your child component, just use a named prop.
I'd say that if you ask yourself the question: "Ok, but what will that generic component render?" is when you should use children
You use props.children on a component which acts as a container and does not know about their children ahead of time.
Basically props.children it is used to display whatever you include between the opening and closing tags of the "containing" component when invoking it.
As mentioned in the React official docs:
Some components don’t know their children ahead of time. This is especially common for components like Sidebar or Dialog that represent generic “boxes”.
We recommend that such components use the special children prop to pass children elements directly into their output:
Simply put, it props.children just displays whatever is put between the opening and closing tags.
As asked in your question, there is not much difference in the use case specified by you.
But, say you had a small left icon the component then passing 'title' as a separate prop would make more sense Eg.
<TextComponent title="Save" src="https://..." />
function TextComponent(props) {
return (
<div>
<img src={props.src}/>
<button>{props.title}<button/>
</div>
);
}
When you do know what your props are, use props. Otherwise, use children (aka containment).
Other than that, using props/children in your case depends on what you want to pass:
If its a single props (like item), than it doesn't matter which method you'll choose.
Else, you should check what you are passing inside children as you might pass other values which you don't want to render.
I would suggest using the selective approach (e.g props.title), since you are always aware of whats going inside your components.
Related
I still don't get why we need a prop(s) in react, seriously. Why can't we just declare everything we need as an argument or parameter in the child component, then declare it, why do we have to declare it in a parent element then pass the props to the child component then catch it. I don't understand why. It seems a bit confusing, I'm yet to see the why in it
Props are useful in the case that you have a controller in the parent component and you want to pass the value of that controller to the child to make a certain action. The replacement for props would be to store everything globally in redux or mobx, but that needs much work. for example
const ParentComponent = () =>{
const [flag, setFlag] = useState(false)
return(
<div>
<button onClick={()=>setFlag(!flag)}>click me!</button>
<ChildComponent flagValue={flag}/>
</div>
)
}
as in the example for some reason the button that changes the flag is in the parent and you need to use that value in the ChildComponent. So here you benefit a lot from using props.
Also in writing a cleaner code and drier one so as not to repeat the same values in different react components
You might not be familiar with React if you ask such questions (no anger at all). It's one of the main concepts of the React library.
You can easily split a huge component into smaller pieces. But then, you need to provide the same data here and there. To prevent repeating yourself (DRY - don't repeat yourself), you can share the prop with many child components.
If you are interested in React - check the documentation.
It's one of the prettiest documentation I've ever read.
prop changes trigger UI re-render for the child component.
That's one of the props of using props.
I can't find a distinction between props.render and props.children, so I'm starting to believe that they achieve the same thing BUT in different ways.
Is this a correct assumption? If not; how are they different (beside how they are implemented), and when should I use one over the other?
render-props can address your questions.
children is part of the Top-level API, meaning, it is intrinsic to a react component. The children prop can be just about anything react can render, typically an element or array of elements, but can be a function similar to a "render prop".
The "render" prop, however, is not intrinsic, it can be anything really... so long as it is a function.
Using props other then render
It’s important to remember that just because the pattern is called
“render props” you don’t have to use a prop named render to use this
pattern. In fact, any prop that is a function that a component uses to
know what to render is technically a “render prop”.
I have one component, it contains two other components. First "NotifyMessage" component is rendered for the whole page. Second "NotifyMessage" component is rendered just only inside pop up. Both components subscribe to the redux store and get appropriate message and type (success or error) from there. Currently, if something happens - "NotifyMessage" component rendered in both places (popup and whole page). What is the best approach to separate render logic? I'd like to render only one component in one place.
create a flag State , say "compAlreadyShown" with boolean value. Use it to conditionally show hide in popup.
I've added another message to my redux store for "pop'ups" cases and pass it to my common "NotifyMessage" component as a children. For now I've two sources of truth for messages in my store instead of one. May be there is a better solution but it fix my problem.
I've realised that none of the components I write use {this.props.children}.
I tend to compose my components the way the official docs state at the top of https://facebook.github.io/react/docs/multiple-components.html.
Is nesting the components like this...
<A>
<B />
<C />
</A>
...beneficial over composing them like this?:
A.js
render() {
<B />
<C />
}
Presuming that's the right terminology, what am I missing?
In my applications I rarely use this.props.children, because I often know specifically what children I want to render. In libraries, or components written to be re-used outside of a specific component hierarchy, I've seen it often. I think this.props.children has more relevance to that use-case.
Edit: I thought I'd elaborate on some cases that this.props.children can come in handy. One such example is when creating components which follow the 'render prop' pattern. i.e. I've got some components that require pulling data in from multiple 'render prop' HoC's, such as an Apollo Query component as well as a state management HoC. I combined all my different data sources into one HoC and then called children as a function, passing in the result of pulling out all the data I needed. That being said these days I prefer and look forward to wider adoption of Hooks as an alternative to render props.
Really any component which you want to render arbitrary children; another example I've used props.children is when creating a HoC that required a user be authenticated before rendering the child, redirecting to a login screen when the user isn't logged in. I could wrap any of my 'protected' screen components with this auth HoC.
It's still something the majority of my components don't use, but just another tool to be applied when the situation warrants.
I'd say it would be useful when you don't know what you want to render.
For instance, you have a tooltip wrapper, let's say it's A component in your scenario, and you can use it to pass different content:
<A>
<div>Some text...</div>
<ImageComponent /> // render an image as well
</A>
Or:
<A>
<div>Only text</div>
</A>
Some components don't know their children ahead of time. This is especially common for components like Sidebar or Dialog that represent generic "boxes".
We recommend that such components use the special children prop to pass children elements directly into their output:
Read More...
Children is a special prop that can be passed from the owners to the components defined inside their render method. It allows us to customize a structure of a component.
With props, a child component keeps its structure under the full control and only certain attributes or values are allowed to be passed. The structure of the component is hard coded.
In the React documentation, children property is described as opaque, because it is a property that does not tell anything about the value it contains. As a result it allows a client/parent to customize a structure.
We can also say, that the components defines only a kind of basic template/structure, for instance by providing a kind of "header". And the consumer reuses this header structure, by adding children.
I'd like to make a React component that, when inserted inside any other component, will display its state in a DIV floated to the right of the screen. Let name it StateExplorer.
Because many StateExplorers can be used on the same page, the DIVs will stack with the same z-index.
The challenge here is to make StateExplorer easily non-verbosely embeddable, like this:
<SomeComponent>
<StateExplorer/>
....
</SomeComponent>
The particular issue here is: how do I hook on componentWillUpdate() so that the StateExplorer always displays up-to-date state? I could use a mixin, but that throws 2 problems:
componentWillUpdate() can be implemented already in the parent component
adding a mixing adds more verbosity; the ideal case is to just add StateExplorer and nothing more.
P.S. I know about React Debug Tools, but it's not so convenient in some cases and adds extra steps before you can see state of a single component.
Sounds like what you need is a Higher-order component.
Here is a good article about it: https://medium.com/#dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750