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.