But first, What are props?

Is a pattern to share information between a parent component and a child component, where the parent component sets attributes and sends them to the child component as an object. Is important to know that this patter works in a unilateral way, it means that the information is just shared between parent to child and not in the other way.

How to use props?

Props are used for components in react, but the syntax will be vary depending on the type of the component.

For the following examples, we will use them in functional components. At the end of the blog we will do the same examples but with class components.

Props parent to child

We have the example of 2 files called App and Children where the app will be the parent component and the children component will be the child component. In our component, we declared an object called information, a function that makes a sum and 2 variables con strings values.

We declared the component child Children as part of the render of the component and assign attributes ( any valid name for HTML attributes) all this will be equal to the variable o function to send as a prop.

Copy
// App.js
import React from "react"
import Children from "./Children"
import "./style.css"

export default function App() {
  const information = { number: 25, name: "props" }

  const funSum = num => {
    return num + 2
  }
  const title = "Hello guys I'm sending props!! ๐Ÿ‘‘"
  const content = "ohh another prop this is good!!"
  return (
    <>
      <Children
        title={title}
        content={content}
        information={information}
        sum={funSum}
      />
    </>
  )
}

The functional component Children receive props as the first parameter of the function as an object, each name of the property of this object set as an attribute in the parent component will be the name of the prop in the child component. A common practice is to deconstruct the received object.

Copy
// Chindren.js
import React from "react"
import "./style.css"

export default function Children({ title, content, information, sum }) {
  console.log(sum(5)) // 7

  return (
    <div>
      <h1>{title}</h1>
      <p>{content}</p>
      <p>{information.number}</p>
      <p>{information.name}</p>
    </div>
  )
}

Giving us as a result:

scope showed as a building

If you want to check the example in real life, click on this link! https://stackblitz.com/edit/props-one?file=src/Children.js

Props child to parent

Yes, you are reading well as I said before props just work in a unilateral way a send information just from the parent component to the child component, but there is a way with props to send information from the child component to the parent component and is using callbacks!!!

Having an example from before, we declared an input that asks you your name, and at the same time, you are writing your name this will be showing under the input the name you wrote. but this will be rendered from the App component.

In this example, in the App component, we declared a state where are we going saving the name that will receive from the child component to be used for the app component, after this is declared a function that is sent as a prop to our child component under the name onChange. And for the last is rendered a message with the name written.

Copy
import React, { useState } from "react"
import Children from "./Children"
import "./style.css"

export default function App() {
  const [name, setName] = useState("")

  const handleNameOnChange = n => {
    setName(n)
  }
  return (
    <>
      <Children onChange={handleNameOnChange} />
      <p> Your name is :{name}</p>
    </>
  )
}

On another hand, we have the children component that received as a parameter the function onChange there is an input in the render component that receives an event handler. In the function called handleChange that receives the event of the written name is here where the magic happens, because we use the function from the props and we assign as an argument the information of the event that will be executed in our component app.

Copy
import React from "react"
import "./style.css"

export default function Children({ onChange }) {
  const handleChange = e => {
    onChange(e.target.value)
  }

  return (
    <div>
      <label>name</label>
      <input type="text" id="fname" name="fname" onChange={handleChange} />
    </div>
  )
}

Giving us as a result:

scope showed as a building

If you want to check the example in real life, click on this link!!! https://stackblitz.com/edit/two-props?file=src/Children.js

Props and spread syntax

There are cases when you need to pass the same props through under levels on these cases you can use the syntax spread, but you have to have in mind that just work if that you want to send is an object o can be in an object.

in this example, we have in the parent component App a series of variables that contain the names of the characters of friends, but this will be rendered for the direct child component and the childrenTwo component is the child of the child (yes kind of complex)

Copy
import React, { useState } from "react"
import Children from "./Children"
import "./style.css"

export default function App() {
  const nameOne = "Rachel"
  const nameTwo = "Ross"
  const nameThree = "Monica"
  const nameFour = "Chandler"
  const nameFive = "Joey"

  return (
    <>
      <div>Friends ๐Ÿ‘ฉ๐Ÿป๐Ÿ‘ฑ๐Ÿปโ€โ™€๏ธ๐Ÿ‘ฉ๐Ÿฝ๐Ÿง‘๐Ÿป๐Ÿ‘ฆ๐Ÿป๐Ÿ‘จ๐Ÿปโ€๐Ÿฆฑ</div>
      <Children
        one={nameOne}
        two={nameTwo}
        three={nameThree}
        four={nameFour}
        five={nameFive}
      />
    </>
  )
}

Now in our component Children we received those props as an (object) and we deconstruct the object props to save in another variable the rest of the object that will be sent to the ChildrenTwo component. In the object Children we rendered the first two names and declared child ChildrenTwo component turning Children as the component parent.

Copy
import React from "react"
import ChildrenTwo from "./ChildrenTwo"
import "./style.css"

export default function Children(props) {
  const { one, two, ...restProps } = props

  return (
    <div>
      <p>{props.one}</p>
      <p>{props.two}</p>
      <ChildrenTwo {...restProps} />
    </div>
  )
}

In the component child ChindrenTwo we received the props object and rendered the missing names.

Giving us as a result:

scope showed as a building

If you want to check the example in real life, click on this link!!! https://stackblitz.com/edit/props-three?file=src/ChildrenTwo.js

Props with default value

In some cases, we want the props of the component to have a default value that will be used if the parent component doesn't send information to the child component.

In this example, we have the parent component App that rendered a button that when it clicked it will show a phrase but by defect will show another phrase.

Copy
import React, { useState } from "react"
import Children from "./Children"
import "./style.css"

export default function App() {
  const [state, setState] = useState()

  const handleClick = () => {
    setState(true)
  }

  return (
    <>
      <button onClick={handleClick}>Click me!!! ๐Ÿ•</button>
      <Children state={state} />
    </>
  )
}

The rendered of this phrase is in the child component Children that it will receive the props value true and will print a phrase, if this is not received, the value will be by default false.

Copy
import React from "react"
import ChildrenTwo from "./ChildrenTwo"
import "./style.css"

export default function Children({ state = false }) {
  return <div>{state ? <p>On!!! ๐Ÿ˜ฎ</p> : <p>Off!!! ๐Ÿ˜ด</p>}</div>
}

Giving us as a result:

scope showed as a building If you want to check the example in real life, click on this link!!! https://stackblitz.com/edit/props-four?file=src%2FChildren.js

Another way to assign props by defect

Using the syntax defaultProps in the last example the App component will be declared as the same. but at the moment to receive the prop the Children component is declared the name of the component follow by a dot and the defaultProps syntax, and declared the object where we assign the value by default of the properties. Important to know this will be declared outside of the child component.

Copy
import React from "react"
import "./style.css"

export default function Children({ state }) {
  return <div>{state ? <p>On!!! ๐Ÿ˜ฎ</p> : <p>Off!!! ๐Ÿ˜ด</p>}</div>
}

Children.defaultProps = {
  state: false,
}

Giving us as a result:

scope showed as a building

If you want to check the example in real life, click on this link!!! https://stackblitz.com/edit/props-five?file=src/Children.js

Props and typescript

To use props in react with typescripts necessary write more code and declare interfaces, so we need to go step by step. We must clarify that in this part of the blog we will be using the same previously examples and were just explain the typescript part.

Props parent to child

As a parent component is not necessary to declare something extra for typescript. But in the child component is necessary to declare an interface for the props we are going to receive and the type of each one, as an addition, we need to declare in the function component the syntax React.FC<Props>, that tells to typescript that we have a functional component and its receiving Props

Copy
import React from "react"
import "./style.css"

interface Props {
  title: string
  content: string
  information: { number: number; name: string }
  sum: (n: number) => number
}

const Children: React.FC<Props> = ({ title, content, information, sum }) => {
  console.log(sum(5)) // 7

  return (
    <div>
      <h1>{title}</h1>
      <p>{content}</p>
      <p>{information.number}</p>
      <p>{information.name}</p>
    </div>
  )
}

export default Children

Giving us as a result:

scope showed as a building If you want to check the example in real life, click on this link!!! https://stackblitz.com/edit/props-one-typscrit?file=Children.tsx

Props child to parent

Taking a previous example of the input, the parent component App is the one that is sending the props it's not necessary to add something for typescript. We need to add the interface for the child component Children we declared the function onChange and add the syntax to the functional component for typescript. As you can see in this example we are not doing any changes for the parent component because the component its receiving the information by a callback but sending this function as a props.

Copy
import React from "react"
import "./style.css"

interface Props {
  onChange: (n: string) => void
}

const Children: React.FC<Props> = ({ onChange }) => {
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    onChange(e.target.value)
  }

  return (
    <div>
      <label>name</label>
      <input type="text" id="fname" name="fname" onChange={handleChange} />
    </div>
  )
}

export default Children

Giving us as a result:

scope showed as a building If you want to check the example in real life, click on this link!!! https://stackblitz.com/edit/props-two-typescrit?file=Children.tsx

Props and class components

Props parent to child

The class components receive props as properties of the instance of the component and it could access to them using the syntax this.props

We have the previous example but this time with class components and props will be sent in the same way to the child component.

Copy
import React from "react"
import Children from "./Children"
import "./style.css"

class App extends React.Component {
  state = {
    information: { number: 25, name: "props" },
    title: "Hello guys I'm sending props!! ๐Ÿ‘‘",
    content: "ohh another prop this is good!!",
  }

  funSum = num => {
    return num + 2
  }
  render() {
    return (
      <div>
        <Children
          title={this.state.title}
          content={this.state.content}
          information={this.state.information}
          sum={this.funSum}
        />
      </div>
    )
  }
}

export default App

In the component Children who receive the props, it will receive those as properties of the class and they don't have to be extracted from any object. We declared the props with the keyword this (magic) which one will be rendered.

Copy
import React from "react"
import "./style.css"

class Children extends React.Component {
  render() {
    console.log(this.props.sum(5)) // 7
    return (
      <div>
        <h1>{this.props.title}</h1>
        <p>{this.props.content}</p>
        <p>{this.props.information.number}</p>
        <p>{this.props.information.name}</p>
      </div>
    )
  }
}

export default Children

Giving us as a result:

scope showed as a building If you want to check the example in real life, click on this link!!! https://stackblitz.com/edit/props-one-class?file=src%2FChildren.js

Props and typescript in class components

In the parent component App we declared the props with no extra. But in the child component children we declared the interface whit the props as properties and their types, we modify the syntax of the class component adding <Props> and declared the props with the keyword this (magic!).

Copy
import React from "react"
import "./style.css"

interface Props {
  title: string
  content: string
  information: { number: number; name: string }
  sum: (n: number) => number
}

class Children extends React.Component<Props> {
  render() {
    console.log(this.props.sum(5)) // 7
    return (
      <div>
        <h1>{this.props.title}</h1>
        <p>{this.props.content}</p>
        <p>{this.props.information.number}</p>
        <p>{this.props.information.name}</p>
      </div>
    )
  }
}

export default Children

Giving us as a result:

scope showed as a building If you want to check the example in real life, click on this link!!! https://stackblitz.com/edit/props-typscrit-class?file=Children.tsx