React Props vs State

Posted on October 29, 2020


In React library, props and states are both means to make a component more dynamic. Props (or properties) are inputs passed down from a parent component to its child component. On the other hand, states are variables defined and managed by the component.

For example, let’s say we have a that calls a :

function ParentComponent(){
  return <ChildComponent />
}

You can pass a prop from ParentComponent into ChildComponent by adding new attributes after the component name. For example, the name prop with value John is passed to ChildComponent below:

function ParentComponent(){
  return <ChildComponent name="John" />
}

After that, the child component will accept the props as the first argument. What to do with the prop being passed down to the child is of no concern to the parent component. You can simply output the name prop like this:

function ChildComponent(props){
  return <p> Hello World! my name is {props.name}</p>
}

In most real projects, the child component would probably render conditionally based on the props being passed into it:

export default function ParentComponent() {
  return <ChildComponent name="John" />
}

function ChildComponent(props) {
  if (props.name) {
    return <p> Hello World! my name is {props.name}</p>
  }
  return <p>Name not found. Please send me a "name" . . . </p>
}

Passing down multiple props

You can pass as many props as you want into a single child component, just write the props next to the previous. Here’s an example:

function ParentComponent() {
  return (
    <ChildComponent
      name="John"
      Age={29}
      isMale={true}
      hobbies={["read books", "drink coffee"]}
      occupation="Software Engineer"
    />
  );
}

Oh and please remember: you need to pass either a string or a JavaScript expression inside curly brackets as the value of props. This is because your component call is in JSX syntax, and you need to use curly brackets to write an expression.

Props are immutable

Meaning that a prop’s value can’t be changed no matter what happens. The following example will still output “John” instead of “Mark”:

function ChildComponent(props) {
  if (props.name) {
    props.name = "Mark";
    return <p> Hello World! my name is {props.name}</p>;
  }
  return <p>Name not found. Please send me a "name" . . . </p>;
}

But what if you need variables that might change later? This is where state comes in. States are arbitrary data that you can define, but they are initialized and managed by a component. Here’s how you define a function component state:

function ParentComponent() {
  const [name, setName] = React.useState("John")
}

In the example below, the name state is initialized by calling React.useState function. The useState function returns an array with two elements, the first element is the value of the state (in this case, “John”) and the second element is a function that you need to call to change the state value.

The square bracket surrounding both name and setName is a destructuring array assignment, meaning we take the return value of useState function, and directly assign them to name and setName variables.

Please note that you can’t change state value by reassigning the variable:

function ParentComponent() {
  const [name, setName] = React.useState("John")

  name = "Mark"
}

You need to use the function returned by useState as the second element:

function ParentComponent() {
  const [name, setName] = React.useState("");
  if (name === "") {
    setName("Mark");
  }
}

Also, never call on the set function at the top-level since it will cause an infinite loop:

function ParentComponent() {
  const [name, setName] = React.useState("");
  setName("Mark");
}

You can pass both state and its update function into any child component as a prop when required:

export default function ParentComponent() {
  const [name, setName] = React.useState("John");
  return <ChildComponent name={name} setName={setName} />;
}

When a child component needs the state to change, you can do so by calling on the setName function. In the following example, I put a button to change the value of name when it gets clicked:

function ChildComponent(props) {
  if (props.name) {
    return (
      <>
        <p> Hello World! my name is {props.name}</p>
        <button onClick={() => props.setName("Mark")}>Change name</button>
      </>
    );
  }
  return <p>Name not found. Please send me a "name" . . . </p>;
}

Here’s a codesandbox example that you can play with:

Conclusion

You’ve just learned the difference between props and state in React. Both features are simply arbitrary variables that you can use to make your React components more dynamic. In most cases, states are initialized at top-level components and passed down as props into children components.

When you need to change the prop value, the child component can send a signal — usually function call when a button is clicked or something similar — to the parent component to change the state. This will make the props value being passed down from the parent component to child component changes.

The components will then render the user interface accordingly.

More about React:

Level up your React skill today 🔥

Build FOUR projects using React with my latest book.

Structured knowledge from beginner to experienced level!

Learn more