This content originally appeared on Envato Tuts+ Tutorials and was authored by Kingsley Ubah
React is a JavaScript library built by Facebook for composing user interfaces in single-page applications. In this tutorial, we'll discuss what events are, how they work in React, and how to set up events handlers on a controlled form in your React application.
To follow along with this tutorial, just create a new React app with create-react-app
:
npx create-react-app my-project-name
You can also find the source code for this tutorial in our GitHub repo.
Controlled Inputs in React
Controlled inputs are basically a way of setting up inputs and forms in React, so that we can track their values. This involves storing the value typed into the input by the user inside some form of state.
Consider the following component for example:
import { useState } from "react"; function UserProfile(props) { const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [age, setAge] = useState(0); const [password, setPassword] = useState(""); return ( <div className="App"> <h2>Provide your profile details</h2> <form> <div> <label for="name-field">Name</label> <input id="name-field" type="text" value={name} /> </div> <div> <label for="email-field">Email</label> <input id="email-field" type="text" value={email} /> </div> <div> <label for="age-field">Age</label> <input id="age-field" type="number" value={age} /> </div> <div> <label for="password-field">Password</label> <input id="password-field" type="text" value={password} /> </div> <button type="button">Submit</button> </form> </div> ); } export default UserProfile;
As you might have guessed, UserProfile
is a simple component that renders a form through which users can submit their profile details. You can save it in src/UserProfile.js within your app folder.
The input in this component is a controlled input. We began by importing useState()
from React, and we then went on to define the initial states for the various input fields.
Each of the values defined in state is directly bound to its respective input. This creates a two-way flow of data between the state and the form inputs.
Let's go on and import the UserProfile
component inside of src/App.js, the root component:
import UserProfile from './UserProfile'; function App() { return ( <div className="App"> <UserProfile /> </div> ); } export default App;
Finally, let's update the CSS in src/App.css. Replace the existing file with the following styles:
.App { text-align: left; margin-left:20%; margin-right:20%; } label { display: inline-block; margin-right: 1em; width: 4em; } input { width: 15em; }
When we save the file and run the local dev server, the component will be rendered on the app.
Now we have bound the view (the form) to the model (aka the state). However, any data supplied through the form at this point will not be stored in the state. This is because React has no way of knowing when the user types into the input field on the UI.
To connect the state to the view, we'll need to set up event handlers on the various form inputs. This brings us to the next topic, Events.
React Events
An event is an action that could be triggered as a result of the user action or a system generated event. An event could be a mouse click, the loading of a web page, user pressing a key, resizing the window, as well as other UI interactions.
To make our component UserProfile
into a fully controlled component, we need to set up event handlers on the inputs. Here's what the name-field
input element will look like:
<input id="name-field" type="text" value={name} onChange={(e) => setName(e.target.value)} />
You can update the email, age, and password inputs in a similar way, calling the setEmail
, setAge
, and setPassword
functions provided by the useState
hook.
The onChange
event triggers whenever the value of the input is changed. When this event is fired, we simply call the relevant setter method to update a corresponding part of the state with new values.
Inside the setter method, we define a callback function that takes the event (e
) as an argument. Through this event, we access whatever value the user typed into the input by accessing event.target.value
.
Now any data supplied through the form will be automatically stored in the state. We can observe this by logging the state values to the console when the submit button is clicked. First create a function to log the state and put it in the UserProfile
component above the return statement.
const logState = () => { console.log(name); console.log(email); console.log(age); console.log(password); }
Then, update the submit button to call this function when it is clicked.
<button type="button" onClick={ logState }>Submit</button>
When the button is clicked, the values will be logged onto the console.
Conversely, whenever a value in the state is changed for any reason, React will in turn update the value that we see in the input field.
This is otherwise called the two-way binding of data. That is data flows from view to state, and state to view.
Emitting Events in React
Suppose we want to send data from a child component to whichever component uses it (aka the parent)—we do this by emitting an event to the parent component.
In our case, the component App
is the parent of UserProfile
. We can send the state from UserProfile
to App
by emitting an event. First create a function to emit the event in the UserProfile component:
const emit = () => { props.callback({name: name, email: email, age: age, password: password}); }
Then, update the submit button to call that emit function.
<button type="button" onClick={ emit }>Submit</button>
On clicking the button, we emit the values for name, email, age and password from the state to the parent component, which is App
in our case.
Inside App
, we'll import useState
:
import { useState } from 'react';
Create state for the data from the form:
const [data, setData] = useState({});
And handle the event emitted by UserProfile
:
return ( <div className="App"> <UserProfile callback={importData} /> <p>Name: {"name" in data ? data["name"] : "No name To Display" }</p> <p>Email: {"email" in data ? data["email"] : "No email To Display" }</p> </div> );
We began by importing useState()
and instantiating it with an empty object. Then we defined the function importData
. This is the callback function to be called by UserProfile
. This function takes data from UserProfile
and updates App
's state with it.
In the template, we pass down this function to UserProfile
as props which is exactly how we were able to access it from within UserProfile
.
Whenever we pass values into the form input and click on submit, the values will be emitted to the parent, to display in the template:
Wrapping Up
I hope this tutorial helped you understand React events better. In this tutorial, we went over controlled components, event handling and event emission with some React code examples.
You should now be able to set up a controlled component in React, bind state data with controlled inputs and emit data from child component to parent component.
If you have any questions related to this topic, please let me know in the comments.
This content originally appeared on Envato Tuts+ Tutorials and was authored by Kingsley Ubah
Kingsley Ubah | Sciencx (2016-12-11T09:52:12+00:00) Understanding Forms and Events in React. Retrieved from https://www.scien.cx/2016/12/11/understanding-forms-and-events-in-react/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.