How to React When Ur Sil Baby Use Ur Baby Dress

The core of React is components. You lot can nest these components like you lot would nest HTML tags, which makes is easy to write JSX since it resembles markup.

When I first learned React, I thought "Apply props.children and that's information technology. I know everything about children" Boy, was I wrong.

Because we're working with JavaScript, nosotros tin can modify children. We can ship special properties to them, decide if nosotros want them to render or not and more often than not manipulate them to our volition. Permit's dig into the power of children in React.

Table of contents

  • Child components
    • Everything tin can be a child
    • Function as a child
  • Manipulating children
    • Looping over children
    • Counting children
    • Converting children to an array
    • Enforcing a single kid
  • Editing children
    • Changing children props
    • Immutably cloning elements
  • Summary

Child components

Permit's say we take a <Grid /> component which tin can contain <Row /> components. Y'all'd use it like and then:

                          <Grid>              <Row              />              <Row              />              <Row              />              </Grid>                      
The rendered components, one Grid containing three rows
(Alive demo)

These iii Row components are passed to the Grid component as props.children. Using an expression container (that's the technical term for those squiggly brackets in JSX) parents can render their children:

                          class              Filigree              extends              React              .              Component              {              return              ()              {              return              <              div              >              {              this              .              props              .              children              }              <              /div              >                            }              }                      

Parents can also make up one's mind not to return whatever children or to manipulate them earlier rendering. For instance, this <Fullstop /> component does not render its children at all:

                          class              Fullstop              extends              React              .              Component              {              render              ()              {              render              <              h1              >              Hi              world              !<              /h1              >                            }              }                      

No thing which children you laissez passer to this component, it volition e'er show "Hi world!" and nothing else. Full stop.

Notation: The <h1> in the case above (much like all the HTML primitives) does render its children, in this case 'Hello Earth!'.

Everything tin be a kid

Children in React don't have to be components, they can be annihilation. For example, nosotros can laissez passer our <Grid /> component from above some text as children and information technology'll work perfectly fine:

                          <Grid>Hello globe!</Grid>                      
The grid component rendering 'Hello world!'
(Live demo)

JSX volition automatically remove whitespace on the beginning and ending of a line as well as blank lines. It also condenses blank lines in the heart of string literals into one space.

This means all of these examples volition return the same affair:

                          <Filigree>Hello world!</Grid>              <Grid>              Hello world!              </Grid>              <Grid>              Hello   globe!              </Filigree>              <Grid>              Howdy world!              </Grid>                      

You can likewise mix and match multiple types of children perfectly fine:

                          <Filigree>              Here is a row:              <Row              />              Here is another row:              <Row              />              </Filigree>                      
The grid component rendering two rows and some text
(Alive demo)

Function as a child

We can pass whatsoever JavaScript expression every bit children. This includes functions.

To illustrate what that would expect like, this is a component which executes a office passed to it as a child:

                          form              Executioner              extends              React              .              Component              {              render              ()              {              // Come across how we're calling the kid as a office?              //                        ↓              render              this              .              props              .              children              ()              }              }                      

Y'all'd utilise this component like so:

                          <              Executioner              >              {()              =>              <              h1              >              Hello              Globe              !<              /h1>              }                            <              /Executioner              >                                    

This specific example isn't useful, of course, but it shows the idea.

Imagine you had to fetch some data from a server. You could do this in a variety of ways, but it's possible with this function-as-a-child pattern:

                          <              Fetch              url              =              "api.myself.com"              >              {(              outcome              )              =>              <              p              >              {              outcome              }              <              /p>              }                            <              /Fetch              >                                    

Spend a minute to play around with this bin and see if you tin can figure out how to brand this piece of work. (hither is my go at it)

Don't worry if this is over your caput. All I want is that y'all're not surprised when you see this in the wild. With children, anything goes.

Manipulating children

If you have a look at the React docs you will see it says that "children are an opaque data structure". What they are essentially telling united states of america is that props.children can be any type, such every bit an assortment, a part, an object, etc. Since you tin pass anything, yous can never know for sure.

React provides a agglomeration of helper functions to make manipulating children easy and painless. These are available at React.Children.

Looping over children

The two nearly obvious helpers are React.Children.map and React.Children.forEach. They work exactly like their array counterparts, except they as well work when a function, object or annihilation is passed equally children.

                          class              IgnoreFirstChild              extends              React              .              Component              {              render              ()              {              const              children              =              this              .              props              .              children              render              (              <              div              >              {              React              .              Children              .              map              (              children              ,              (              child              ,              i              )              =>              {              // Ignore the first child              if              (              i              <              one              )              return              return              child              })}              <              /div              >                            )              }              }                      

The <IgnoreFirstChild /> component hither maps over all its children, ignoring the commencement child and returning all the others.

                          <              IgnoreFirstChild              >              <              h1              >              First              <              /h1              >                            <              h1              >              Second              <              /h1> /              /              <-              Only              this              is              rendered              <              /IgnoreFirstChild              >                                    
Some text saying 'Second'
(Live demo)

In this case, we could've also used this.props.children.map. Only what would've happened if somebody passed a function equally a child? this.props.children would've been a function instead of an array, and we would've had an fault! 😱

TypeError: this.props.children.map is not a function

With the React.Children.map function though, this is no trouble whatsoever:

                          <              IgnoreFirstChild              >              {()              =>              <              h1              >              First              <              /h1>} /              /              <-              Ignored              💪              <              /IgnoreFirstChild              >                                    

Counting children

Since this.props.children tin can be whatever type, checking how many children a component has turns out to be rather hard! Naïvely doing this.props.children.length would intermission when passed a String or a function. Nosotros'd have i child, "How-do-you-do World!", but the .length would be reported as 12 instead!

That's why nosotros have React.Children.count:

                          class              ChildrenCounter              extends              React              .              Component              {              render              ()              {              render              <              p              >              React              .              Children              .              count              (              this              .              props              .              children              )              <              /p              >                            }              }                      

It returns the number of children no thing what type they are:

                          // Renders "one"              <              ChildrenCounter              >              2d              !              <              /ChildrenCounter              >                            // Renders "2"              <              ChildrenCounter              >              <              p              >              Commencement              <              /p              >                            <              ChildComponent              />              <              /ChildrenCounter              >                            // Renders "3"              <              ChildrenCounter              >              {()              =>              <              h1              >              First              !<              /h1>              }                            2nd              !              <              p              >              Third              !<              /p              >                            <              /ChildrenCounter              >                                    

Converting children to an array

As a last resort, if none of the above methods fit your demand, you can convert your children to an assortment with React.Children.toArray. This would exist useful if you needed to due east.thousand. sort them:

                          class              Sort              extends              React              .              Component              {              return              ()              {              const              children              =              React              .              Children              .              toArray              (              this              .              props              .              children              )              // Sort and return the children              render              <              p              >              {              children              .              sort              ().              join              (              ' '              )}              <              /p              >                            }              }                      
                          <              Sort              >              // We use expression containers to brand sure our strings              // are passed as three children, not as 1 string              {              'bananas'              }{              'oranges'              }{              'apples'              }              <              /Sort              >                                    

The higher up example renders the strings, just sorted:

apples bananas oranges
(Live demo)

Note: The array returned by React.Children.toArray doesn't contain children from blazon function, only ReactElement or strings.

Enforcing a single child

If yous remember back to our <Executioner /> component above, it expects only a single child to be passed, which has to be a role.

                          grade              Executioner              extends              React              .              Component              {              render              ()              {              render              this              .              props              .              children              ()              }              }                      

We could try to enforce this with propTypes, which would look something like this:

                          Executioner              .              propTypes              =              {              children              :              React              .              PropTypes              .              func              .              isRequired              ,              }                      

That would log a message to the panel though, something developers could ignore. Instead, we can apply React.Children.only inside our render method!

                          form              Executioner              extends              React              .              Component              {              render              ()              {              return              React              .              Children              .              only              (              this              .              props              .              children              )()              }              }                      

This returns the only child in this.props.children. If there is more than i kid, it throws an error, thusly grinding the unabridged app to a halt—perfect to avoid lazy devs trying to mess with our component. 😎

Editing children

Nosotros can render arbitrary components as children, but still control them from the parent instead of the component we render them from. To illustrate this, permit's say we take a RadioGroup component which can incorporate a number of RadioButton components. (which render an <input type="radio"> inside a <label>)

The RadioButtons are non rendered from the RadioGroup itself, they are used equally children. This means somewhere in our application nosotros have this code:

                          return              ()              {              return              (              <              RadioGroup              >              <              RadioButton              value              =              "first"              >              Get-go              <              /RadioButton              >                            <              RadioButton              value              =              "2d"              >              Second              <              /RadioButton              >                            <              RadioButton              value              =              "third"              >              Third              <              /RadioButton              >                            <              /RadioGroup              >                            )              }                      

There is an consequence with this code though. The inputs aren't grouped, which leads to this:

Three radio buttons, all selected
(Live demo)

To grouping input tags together they all need to have the same proper name attribute. We could of course go through and assign a name property to every single RadioButton:

                          <RadioGroup>              <RadioButton              name=              "g1"              value=              "start"              >Start</RadioButton>              <RadioButton              name=              "g1"              value=              "second"              >2nd</RadioButton>              <RadioButton              proper noun=              "g1"              value=              "third"              >Third</RadioButton>              </RadioGroup>                      

Simply that's a) tedious and b) error decumbent. Nosotros have all the power of JavaScript at our fingertips! Tin can nosotros employ that to tell our RadioGroup the name we desire all its children to go and have information technology take care of that automatically?

Changing children props

In our RadioGroup we'll add a new spring method called renderChildren where we'll edit the childrens props:

                          grade              RadioGroup              extends              React              .              Component              {              constructor              ()              {              super              ()              // Bind the method to the component context              this              .              renderChildren              =              this              .              renderChildren              .              bind              (              this              )              }              renderChildren              ()              {              // TODO: Alter the name prop of all children              // to this.props.name              return              this              .              props              .              children              }              render              ()              {              return              (              <              div              className              =              "group"              >              {              this              .              renderChildren              ()}              <              /div              >                            )              }              }                      

Let's offset by mapping over the children to get each individual child:

                          renderChildren              ()              {              return              React              .              Children              .              map              (              this              .              props              .              children              ,              child              =>              {              // TODO: Change the name prop to this.props.proper noun              render              kid              })              }                      

How tin nosotros edit their properties though?

Immutably cloning elements

This is where the concluding helper method of today comes into play. As the name suggests, React.cloneElement clones an chemical element. We pass it the chemical element we want to clone as the first argument, and then every bit a second argument we can pass an object of props nosotros want to be assault the cloned element:

                          const              cloned              =              React              .              cloneElement              (              chemical element              ,              {              new              :              'yeah!'              })                      

The cloned element will at present have the new prop set up to "yep!".

This is exactly what nosotros demand to finish our RadioGroup. Nosotros clone each child and fix the proper name prop of the cloned child to this.props.name:

                          renderChildren              ()              {              return              React              .              Children              .              map              (              this              .              props              .              children              ,              kid              =>              {              return              React              .              cloneElement              (              child              ,              {              name              :              this              .              props              .              name              })              })              }                      

The concluding step is to pass a unique name to our RadioGroup:

                          <RadioGroup              proper name=              "g1"              >              <RadioButton              value=              "showtime"              >First</RadioButton>              <RadioButton              value=              "second"              >2d</RadioButton>              <RadioButton              value=              "3rd"              >Third</RadioButton>              </RadioGroup>                      
Three radio buttons, one of them selected
(Alive demo)

It works! 🎉 Instead of manually having to set the name attribute on every RadioButton, we just tell our RadioGroup what nosotros want to the name to be and it takes intendance of that.

Summary

Children brand React components experience similar markup instead of disjointed entities. Using the ability of JavaScript and some React helper functions we can work with them to create declarative APIs and make our lives easier.

Thanks to Karl Horky and Jake Trent.


Liked this post? Sign up for the weekly newsletter!

Be the first to know when a new article is posted and get an inside scoop on the almost interesting news and the freshest links of the week. (I detest spam just equally much as you do, and then no spam, ever. Promise.)


choiwitarsted.blogspot.com

Source: https://mxstbr.blog/2017/02/react-children-deepdive/

0 Response to "How to React When Ur Sil Baby Use Ur Baby Dress"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel