Before State
It's important that a programmer learns to utilize props before picking up State. This is because understanding props and information flow is imperative to building a well organized, structured program. Most of the organization of a program is done through the use of different components. Utilizing components in your program has two main benefits, flexibility and reusability. When you separate your code into components, you make your program more flexible as a whole because individual components can be used and reused in different places.
function Component1() {
return (
<form>
<input type="text" placeholder="First Name"/>
<input type="text" placeholder="Last Name"/>
<button>Submit</button>
</form>
)
}
default export Component1;
Take, for example, a simple First and Last name form. This component can be used in multiple locations for different purposes (What if you need the first and last name of the user? Maybe there's another page where you need the name of the user's family?) without having to repeat the code in those different locations. Components make fixing or adjusting code easier as well. Fixing or adjusting/adding to the component is much easier than scanning through every instance of a form to make the same change multiple times. But what happens when you submit that form? Where would the information go?
Introducing Props
Props are used to send information between components. Because components in react consist of functions that return JSX, information flows through these components in the form of arguments to those functions in the form of props.
function Component1(props) {
Let's say in our form component we want to clarify what we want the user to put into the first and last name form. We can pass a string through the props argument. This happens when we import and call Component1 in a separate parent component.
<Component1 message="Enter your name" />
We can then access this message string in our form (Component1)
function Component1(props) {
const formMessage = props.message;
...
}
But what if we want to submit the form and send that information and send it back to the parent component?
Using Callback Functions in Props
If we wanted to send information back up the file tree, we would have to use a callback function. To make use of the callback function, we would have to build one first.
...
function formCallback(formData) {
console.log(formData)
}
...
<Component1 message="Enter your name" formCallback={formCallback} />
From here we would use the callback in our form component
function Component1(props) {
const formMessage=props.message
function submitHandler(e) {
e.preventDefault()
props.formCallback(e)
}
return (
<form onSubmit={submitHandler}>
<h2>{formMessage}</h2>
<input type="text" placeholder="First Name"/>
<input type="text" placeholder="Last Name"/>
<button>Submit</button>
</form>
)
}
...
Whenever the user clicks on the submit button, the form information would then be sent to the parent component's callback function. From there the information can be used and operated on from the parent component.
But what if we wanted to operate on variables within the child component?
Enter the useState() Hook
State is mainly used in react to retain information between renders. A benefit of this is the ability to use this persisting information in different components. To use useState(), the programmer must import the hook into their code.
import React, { useState } from "react"
From there, a state object can be created in the code. State should be used where the information is relevant but for our purposes, let's say that the form component is a child of two parent components which are also child components of our App component. We want both of App's child components to be able to access the state object, therefore, we'll create it in the App file.
function App() {
const [message, setMessage] = useState("")
return (
<parentComponent1 message={message} setMessage={setMessage} />
<parentComponent2 message={message} setMessage={setMessage} />
)
}
Note that when using the useState() hook, we declare two variables in an array. In simple terms, the first variable (message) is used as a getter, while the second variable (setMessage) is used as a setter.
From here we can access the state variable and set the state variable in both parent components. We can use the setter variable in either to set the message of the variable to
setMessage("Enter your name")
or
setMessage("Enter your mother's name")
and then pass the getter variable to our form through either parent component
<Component1 message={message} formCallback={formCallback} />
from there we can access the message variable in our form
function Component1(props) {
const formMessage=props.message
function submitHandler(e) {
e.preventDefault()
props.formCallback(e)
}
return (
<form onSubmit={submitHandler}>
<h2>{formMessage}</h2>
<input type="text" placeholder="First Name"/>
<input type="text" placeholder="Last Name"/>
<button>Submit</button>
</form>
)
}
Depending on which parent component we use to call the form, the message being displayed at the top will differ. This adds further flexibility to our components because we can add custom elements to our component depending on the context in which we call it. Even if we were to render the form separately, when the setter function of the useState() hook is called, it will re-render the page while retaining the information that we store in the variable.
Overall, it's easy to understand once a programmer gets used to thinking in terms of information flow. However, for the sake of cleanliness, efficiency, and keeping code DRY, programmers must practice storing information in only the relevant places.
Top comments (0)