The State of Taking Props to School
Tags: react, javascript, beginners
Published: 2021-09-18 11:41:03

From my experience as an instructor state and props can really throw React beginners for a loop. The good news is that loop doesn't need to be endless (😅). 

### State & Props: What Are They?
![Very Confused Little Girl](https://media.giphy.com/media/kaq6GnxDlJaBq/giphy.gif?cid=ecf05e47gs0a01ztemrj14vjzgarsrbjqj231vbvgg949xmp&rid=giphy.gif&ct=g)

> `props` (short for “properties”) and `state` are both plain JavaScript objects. While both hold information that influences the output of render, they are different in one important way: `props` get passed to the component (similar to function parameters) whereas `state` is managed within the component (similar to variables declared within a function).

[Reactjs.com - Component State](https://reactjs.org/docs/faq-state.html)

Uh, yeah, okay... but what does that mean? Well, let's take a look at a real world example. Think way back to your grade school days. Remember field trips? And permission slips?

Your mom, dad or parental guardian had to sign a permission slip in order for you to go on a field trip. You brought that permission slip to your teacher and showed it to them to prove that you were allowed to go. This is a great way to think about state and props.

*I'm going to use hooks and functional components in these examples, but class components will work, too.*

Starting out, the browser looks like this:
![Browser with two divs, "I am the parent." and "I am the child."](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wkxxpiiesm16sqdq1s8q.png)

The `Parent` component is rendered in `App.js`. Here is the starting code for both `Parent` and `Child`:
```js
import Child from './Child';

const Parent = () => {

  return (
    <div className="container">
      <div className="parent">
        <h2>I am the parent.</h2>
      </div>
      <div className="child">
        <Child />
      </div>

    </div>
  );
};

export default Parent;
```

and here is the starting code for `Child`:
```js
const Child = () => {

  return (
    <div className="child-component">
      <h3>I am the child.</h3>
    </div>
  );
};

export default Child;
```

The first thing we're going to do is set up `state` in our `Parent` component. 
```js
const [isSigned, setIsSigned] = useState(false);
const location = "the science museum";
```

The permission slip for the science museum begins in an unsigned state. Now we need to set up some way for our `Parent` to sign the permission slip for their child. We'll stick to a simple click event on a button. The button will also render conditionally, based on the value of our `isSigned` state.

```js
const handleClick = () => {
  isSigned ? setIsSigned(false) : setIsSigned(true);
};

const renderButton = () => {
    return !isSigned ? <button onClick={handleClick}>Sign Permission Slip</button> : <button onClick={handleClick}>You're Grounded!</button>
};
```

We now want to invoke `renderButton` right under our `h2` tag in the `Parent` component. This is what we see in the browser now:
![Parent and Child component with button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6hefq89rjadp33x0tpe.png)

In order to make sure our button *actually works*, we're going to add `{console.log(isSigned)}` inside of our `Parent` component. Our code should look something like this:
```js
const Parent = () => {
  const [isSigned, setIsSigned] = useState(false);
  const location = "the science museum";


  const handleClick = () => {
    isSigned ? setIsSigned(false) : setIsSigned(true);
  };

  const renderButton = () => {
    return !isSigned ? <button onClick={handleClick}>Sign Permission Slip</button> : <button onClick={handleClick}>You're Grounded!</button>
  };

  return (
    <div className="container">
      {console.log(isSigned)}
      <div className="parent">
        <h2>I am the parent.</h2>
        {renderButton()}
      </div>
      <div className="child">
        <Child />
      </div>

    </div>
  );
};
```

This is what we should see after our first button click:
![Signed Permission Slip](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u0nd5yts0zohjqkse23n.png)

and if we click one more time:
![Field trip permission: revoked!](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rh4g4jbpv9o0m27qwv1g.png)

Now that we know everything is working correctly in our `Parent` component, we can start thinking about `props`! Our `Child` needs some way to tell their teacher whether they can or cannot go on the field trip. We need to pass this information down to our `Child`.

```js
<div className="child">
  <Child location={location} isSigned={isSigned} />
</div>
```

This is how we pass information from parent to child. In our `Child` component, we pass the `props` in as an argument.
```js
const Child = (props) => {
  console.log(props)
  return (
    <div className="child-component">
      <h3>I am the child.</h3>
    </div>
  );
};
```
With that `console.log`, we'll see this in browser console:
![Console log of props](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l4zsi875771rlae43nnf.png)

We can make things a little cleaner here by using destructuring!
```js
const Child = ({ location, isSigned }) => {
  console.log(location)
  console.log(isSigned)

  return (
    <div className="child-component">
      <h3>I am the child.</h3>
    </div>
  );
};

export default Child;
```

![Props with destructuring](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iptmsfta37oto0egq7z4.png)

Now that we have access to that data in our `Child` component, we can display that data!

![Functioning permission slip signing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13626f3tp4rs4xy1bkar.gif)

In the `Child` component, we now have a function called `renderPermission`, which renders text conditionally based on the value of `isSigned`.

```js
const Child = ({ location, isSigned }) => {

  const renderPermission = () => {
    if (isSigned) {
      return `I can go on the field trip to the ${location}!`
    } else {
      return `I'm not allowed to go on the field trip to the ${location}.`
    };
  };

  return (
    <div className="child-component">
      <h3>I am the child.</h3>
      {renderPermission()}
    </div>
  );
};

export default Child;
```

Remember that we can't change props! A kid can't forge their parent/guardians signature! Let's try it out.
```js
  const forgePermission = () => {
    console.log('Clicked')
    isSigned = true;
  };

  return (
    <div className="child-component">
      <h3>I am the child.</h3>

      <button onClick={forgePermission}>Forge Signature</button> <br />
      
      {renderPermission()}
    </div>
  );
```

We're including a `console.log` so that we can be sure that our event listener is working.

![A child can't change props](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t07tw5bwkm73jegb0j4z.gif)

We can't do it! They're not changing! Our `Child` component is not re-rendering. Our parent component is in charge of the data and changing it (with state!) and our child component only has the ability to display that data (they're props!).

Here is a look at our finished code:
```js
import { useState } from 'react';
import Child from './Child';

const Parent = () => {
  const [isSigned, setIsSigned] = useState(false);
  const location = "the science museum";


  const handleClick = () => {
    isSigned ? setIsSigned(false) : setIsSigned(true);
  };

  const renderButton = () => {
    return !isSigned ? <button onClick={handleClick}>Sign Permission Slip</button> : <button onClick={handleClick}>You're Grounded!</button>
  };

  return (
    <div className="container">

      <div className="parent">
        <h2>I am the parent.</h2>
        {renderButton()}
      </div>
      <div className="child">
        <Child location={location} isSigned={isSigned} />
      </div>

    </div>
  );
};

export default Parent;
```

```js
const Child = ({ location, isSigned }) => {

  const renderPermission = () => {
    if (isSigned) {
      return `I can go on the field trip to the ${location}!`
    } else {
      return `I'm not allowed to go on the field trip to the ${location}.`
    };
  };

  const forgePermission = () => {
    console.log('Clicked')
    isSigned = true;
  };

  return (
    <div className="child-component">
      <h3>I am the child.</h3>

      <button onClick={forgePermission}>Forge Signature</button> <br />

      {renderPermission()}
    </div>
  );
};

export default Child;
```

That's it! That's `state` and `props` in React. It's as simple as that.











*Cover image from [Austin Pacheco](https://unsplash.com/photos/uZkgI3opcvE?utm_source=unsplash&utm_medium=referral&utm_content=creditShareLink) on [Unsplash](https://unsplash.com)*