React for JavaScript Programmers IV: Props vs. State
One of the more confusing things about React for regular JS programmers is the various way you can pass things down to a component. You have state, you have props, you then have hooks, context API, and so on. Why do you need that many?
<Welcome name="Sara" />;
And you can change the name to anything while reusing the component.
So what's wrong with props? This works for stuff that's one level down. When you are using the component and passing things to it directly. But what if you want to pass something to a component that's inside another component? Or even deeper? Down multiple levels?
You have to redo all the in-between components to "pass-along" the prop. It's VERY messy.
Not to mention props are READ-ONLY.
And what if you want to pass something back, like an input field?
That's why you have state.
In other words, functions cannot have a state. And vice versa. (There are exceptions, which will be discussed a little later).
The common way to fix this is to rewrite the function into a class. Let's do this to the previous "Welcome" function...
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
I personally find this syntax confusing, as it no longer looks like a function. But we need it in this format to put a state in it. (See React.js documentation for how to "convert" a function to a class.)
This is not a good example because we haven't made use of the state yet. And in reality, this does not need to use state at all.
Instead, study the React.js example, where they created a self-containing "clock" component, step by step. Clock will keep its own "this.state.date" (technically just "date", as this means this object, and state is the overall state reference), and other bits will update it, and yet other bits will render it.
The closest analog would be a "local variable" that's unique to the component, except it's kept and tracked by the overall framework.
State lets component to be smarter, have a memory, and make decisions depending on both memory and input. This improves re-use, as the component, being self-contained, can be more easily reused rather than having some code from the parent lifted as well.
On the other hand, state can be kept all the up at the app level and passed down to the component level as needed, many levels down, where using prop is not the smartest idea.
Keep in mind that a component can have its own (sub-) components, and the component can pass props down to the sub-components (its own state, its own props, or combinations thereof).
Thus, how to break up the HTML elements of a page into components can be rather daunting, as you need to decide which components need to be stateful... and which ones do not.
Indeed, instead of just sitting at a keyboard and start typing, React requires you to plan your approach more carefully.
And sometimes, you may need to refactor the code completely to make state work. Or use one of the alternate approaches, such as React Hooks and Context API.
Let's start with props.
Props, short for properties, are really for simple apps, where the components are only one or two levels deep. Here, for example, is a functional component with a prop (straight from Reactjs.org's example).function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
So you can pass a name to the component via props when you use it...<Welcome name="Sara" />;
And you can change the name to anything while reusing the component.
So what's wrong with props? This works for stuff that's one level down. When you are using the component and passing things to it directly. But what if you want to pass something to a component that's inside another component? Or even deeper? Down multiple levels?
You have to redo all the in-between components to "pass-along" the prop. It's VERY messy.
Not to mention props are READ-ONLY.
And what if you want to pass something back, like an input field?
That's why you have state.
Prop vs State
A component with its own state (think of it as a little bit of memory) is not a function, because how it processes its inputs will be dependent on the state.In other words, functions cannot have a state. And vice versa. (There are exceptions, which will be discussed a little later).
The common way to fix this is to rewrite the function into a class. Let's do this to the previous "Welcome" function...
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
I personally find this syntax confusing, as it no longer looks like a function. But we need it in this format to put a state in it. (See React.js documentation for how to "convert" a function to a class.)
This is not a good example because we haven't made use of the state yet. And in reality, this does not need to use state at all.
Instead, study the React.js example, where they created a self-containing "clock" component, step by step. Clock will keep its own "this.state.date" (technically just "date", as this means this object, and state is the overall state reference), and other bits will update it, and yet other bits will render it.
The closest analog would be a "local variable" that's unique to the component, except it's kept and tracked by the overall framework.
State lets component to be smarter, have a memory, and make decisions depending on both memory and input. This improves re-use, as the component, being self-contained, can be more easily reused rather than having some code from the parent lifted as well.
On the other hand, state can be kept all the up at the app level and passed down to the component level as needed, many levels down, where using prop is not the smartest idea.
Keep in mind that a component can have its own (sub-) components, and the component can pass props down to the sub-components (its own state, its own props, or combinations thereof).
Thus, how to break up the HTML elements of a page into components can be rather daunting, as you need to decide which components need to be stateful... and which ones do not.
Indeed, instead of just sitting at a keyboard and start typing, React requires you to plan your approach more carefully.
And sometimes, you may need to refactor the code completely to make state work. Or use one of the alternate approaches, such as React Hooks and Context API.
Comments
Post a Comment