In a previous article, I summarized React as a means to render a collection of elements to a web page using components.
Components are ultimately functions that render elements to a web page.
Since elements have a hierarchical structure, and components are just a means to rendering elements, components are also organized in a hierarchical structure.
By using functions to render elements (instead of typing things directly into an HTML file), React components can dynamically display and render different things to the user based on the flow of data.
Today, I'll be diving into my mental model for understanding React's "flow of data" between components.
Data
Data sounds like a technical term, but it's quite simple. Data is simply information.
Any web application needs information to guide the user to an end goal.
For example, Twitter needs to know your username and password (data/information) in order to log you into the application. It also needs to know recent tweets from your followers (data/information) based on the current date (data/information).
Sources of Data
Since a web application needs data/information to guide the user to an end goal, we'll need to think about what sources of data exist in a web application.
Knowing the different sources of data, we'll be able to clarify how React handles these sources of data for dynamically rendering elements to a web page.
I tend to think that there are 3 potential sources of data in a web application:
1) Data stored locally in your code or on your computer
2) Data that must be fetched/retrieved from another computer
3) Data that is collected from the end user's interactions
Local Data
A React project might initially receive data from another file in the project:
// File A
import someFileWithData from './someFileWithData.js';
// File B (someFileWithData.js)
const data = {
color: 'red',
};
export default data;
Perhaps, it could "hardcode" the data directly in the file that needs it:
// File A
const data = {
color: 'red',
};
// ...
Data From Another Computer
A React project might initially receive data from another computer.
Databases
First off, why would there be data on another computer when you can store data locally as we just saw?
Storing data locally works fine here and there, but typically, the bulk of the data that "runs" a web application is better stored in a database.
A database is essentially storage room for data on a computer. It allows you to store data in an organized way.
Storing data in a database has several advantages:
1) It is optimized for storing large volumes of data. If your data was stored all in your project, it could slow things down.
2) It can be "sourced" by multiple applications. If you needed to share data between two web applications that are different but similar in a company, for example, then a database would have you covered.
3) Databases are optimized for being searched and sorted. Meaning, you need to do less thinking and coding to organize, search, and sort your data since databases.
4) Databases are safer places to store personal information about users (i.e. emails and passwords).
Servers
These databases need to be stored on another computer so that multiple web applications can retrieve the data.
So, we need a computer that will always be running. Another name for a computer that is always running is a server.
Still to this day, the word "server" makes me cringe a little because it seems like such a technical, loaded term. I think of dark closet with a bunch of complex wires.
However, it's quite simple. Again, it is just a computer that is meant to always running.
A server is meant to always be running so that it can "serve," that is make accessible to other computers, applications and databases.
So, data that is initially needed for a React project might be retrieved from a database that is accessible via a server (another computer that is always running).
APIs
Ok, so how does a React project retrieve data from a database that is accessible via a server?
The answer is that you retrieve data from a server using APIs.
"API" stands for Application Programming Interface.
This is just one of those acronyms that you'll have to get used to hearing...
Basically, it's an API is any interface, or means of communication, with another application.
Specifically in our case, we're interested in APIs, means of communication, that interact with a database "served" by an application on a server.
APIs for this specific context are called REST APIs. "REST" stands for "representational state transfer." "Representational state transfer" could be put in plainer words: "organized data transfer," referring to structured/organized data being transferred from a database to an application. "State" is essentially just another word for "data" used by an application.
A REST API, therefore, is the type of API used to by web application to get data from a database running on another server.
A REST API is the middleman. Our application can say "here's what I need from that database over yonder." The REST API says, "sure thing, boss. Here you go!"
Now, like a human conversation, we need to speak to a REST API in a way it will understand.
I won't be diving into that in this article, you can dig more into it on your own if you'd like.
All you need to know, for the purpose of forming a foundation mental model, is that a React project may get data from another computer (server) via an API.
Data Collected From User Interactions
Third and finally, data can be initially retrieved from a React project by collecting user interactions.
For every element on a web page, you can write instructions (code) on how to handle interactions.
In technical terms, an interaction is called an event."
In other words, web elements comes with ways to handle events; you can code event handlers.
For example, let's say that you want to write code to handle if a user clicks on an element (triggering a "click" event).
Here's how you would write the code in React:
<div onClick={() => alert('Clicked!')}>Click Me</div>
If a user clicks the div
element, an alert will be triggered.
In that code, we are handling a user's interaction, but that interaction is not providing us data.
Nevertheless, we can derive data based on a user's interactions:
const [hasClicked, setHasClicked] = useState(false);
// hasClicked --> false
<div onClick={() => setHasClicked(true)}>Click Me</div>
// hasClicked --> true
Don't worry about this React code yet, as I've not yet given a mental model to explain those specifics.
The point is that React has a way to "derive" data/state from a user's interactions.
Now, some web elements allow us to not merely derive data, but to get data as inputted from a user (i.e. username and password).
Data that must be explicitly collected from a user requires an input
element:
<input type="text" value={value} onChange={() => { /*...*/ } />
Above is some React code for handling the event that a user should type text into an input field.
This is what happens when you log into a web application, for example:
To sum things up so far, we've learned that a React project can get data from another file on the same computer, data from a database on a server via an API, or from user interactions via event handlers on a web element.
React State and Props
As I've mentioned before, React is a framework that offers a shorthand way to render web elements and dynamically change them based on the data that can be "sourced" from a variety of sources in a project, as we have just seen.
Let's dive into the React specifics a bit more.
Again, React components are just functions that render a web element:
function Button() {
return <button>Some Button</button>;
}
This component is a function that returns a button
element.
Easy enough.
Now, let's say we want to make this dynamic based on changes in data.
This doesn't usually happen, but for the sake of illustration, let's say we wanted to change the button's text if the user has hovered it.
We want to derive data (whether the user has hovered a button) based on an event (the user hovers).
State
In React, all data that could impact what is rendered by a component needs to be explicitly "stored" as state.
I mentioned before that state, generally speaking, is just data used by an application.
"State", in the React sense, is data that React uses to determine whether refresh/re-render the element returned by a component. If data is stored as React state, then if the data changes, React knows to re-render the element.
Usually, React state is the data that is derived or explicitly provided by the user via event handlers, and data that is retrieved from any API.
Data that is hardcoded/unchanging/static in the same file as the component (or another file) doesn't need to be stored as React state since it will never change. Hence, it will never cause a need for the component to re-render.
On the other hand, data derived from a user's interactions is dynamic (can change while the user is accessing the web application), so it needs to be stored as React state.
Data that is retrieved from a database can change if a user's interaction requires re-fetching/re-retrieving the data from the database. So, it needs to also be stored as React state.
React exposes a function called useState
for you so that you can tell it to store data as state and update the state based on a user's interactions:
const [hasClicked, setHasClicked] = useState(false);
return (
<div onClick={() => setHasClicked(true)}>Click Me</div>
);
The useState
initially called with the "initial state."
It returns 1) the state (hasClicked
) and 2) a function for changing the state (setHasClicked
).
When the state is changed, React knows to re-render the returned element.
Props
Given that React components are just functions for rendering elements to a web page, and elements have a hierarchy, components also have a hierarchy.
Following the City Model discussed in the previous article, we will have city, neighborhood, block, and house components (and hence, elements).
Data can be retrieved at any layer in the city hierarchy. Given that there are 3 layers besides the house (the bottom layer), it is common to have to "pass down" the React state from one higher/parent component to a lower/child component.
React calls data that is passed down to a child component a prop:
function ParentComponent() {
const [hasClicked, setHasClicked] = useState(false);
return <ChildComponent hasClicked={hasClicked} />;
}
These "props," or properties are read-only. Meaning, you only change them by calling the function to set new state that is returned by useState
as we saw in a previous example.
So, it's also common to pass down the function that can update state. That way, a child component can trigger a change. in state.
React knows that if state initialized in a parent component is passed down to children component(s) as props, and that state is updated, then the component that initialized the state and the components that "consumed" that state via props should be refreshed/re-rendered.
In future articles, we'll look into the specifics of React's syntax as well as React's concepts of component lifecycles.
Top comments (0)