MODULE 3
ONE-WAY DATA FLOW
One of the defining characteristics of React that distinguishes it from
most other front-end UI libraries is its use of one-way data flow, also
known as unidirectional data flow.
One-way data flow means that all of the data in a React application flows
from parent components to child components.
Another common way to describe the flow of data in React is “Data
flows down (or downstream), and events flow up (or upstream).”
While one-way data flow eliminates a common cause of complexity and
errors in user interfaces, it can also create confusion and frustration
unless you fully understand the ins and outs of using it to your
advantage
Understanding One-Way Data Flow
: Unidirectional data flow
Unidirectional data flow doesn’t mean that child components can’t send data to parent
components.
Sending data from child components (for example, an input form) to parent components
(for example, the form containing the input) is a critical part of interactivity.
However, one-way data flow does mean that the way you send data from a child
component to a parent component or between sibling components is different from how
you pass data from a parent to a child.
In React, passing data downstream is done using props, like this:
Why One-Way Data Flow?
Two-way data flow, also known as bidirectional data flow, where a
component’s data can be modified by its parent and changes within the
component can directly affect data in the parent, is convenient.
However, it also increases the complexity of a user interface, and this, in turn,
increases the potential for errors.
Bidirectional data flow
In bidirectional data flow, it’s not possible to tell whether the view was updated by the user
interacting with the view or by the data in the model changing.
Data flowing in one direction
The only way that a view (what’s displayed in the browser) can be changed is by changing
the data in the model (which is the state object in React).
PROPS
Props in React are the primary way that data is shared between parent
components and child components. To create a prop, simply give a React
custom element an attribute, using the name=value format.
Inside the component instance created by that element, the attribute
will become a property of the props object.
Here are some key points about props:
➤ A component can receive any number of props.
➤ A prop’s value can be of any type of JavaScript data or an expression that
evaluates to a value or function.
➤ Props are read-only.
Components Receive Props
When you write a JSX element in React, the attributes that you give an element
are passed to the component as properties in an object. For example, consider
this JSX element:
If Taco is a function component, this element is the same as the following
JavaScript function call:
Inside the Taco function’s header, the object passed to the function is given
the name props, which is how you can access it inside of the function:
Props Can Be Any Data Type
The props you pass to a component can be any type of JavaScript data,
including any of the six primitive data types (undefined, Boolean,
Number, String, BigInt, and Symbol) as well as objects, functions, arrays,
and even null.
Because of JSX’s ability to include JavaScript expressions through the use
of curly braces, the data passed to a component through the props
object can be determined through the use of a variable or any JavaScript
expression or function call.
Props Are Read-Only
Once data has been passed to a component using props, that data is
treated as immutable.
This means that although a component receives props, once those props
are values inside the component, your component can’t change them.
The reason for this rule is that React only re-renders components in
response to state changes.
Props are the mechanism for updating components according to state
changes.
If you were to change the value of a prop inside a component, it would
cause the internal data of your component to be out of sync with what’s
displayed in your browser and the value of the prop would be reset by
the parent component with the next render.
In other words: changing props inside a component won’t have the
effect that you want. If you attempt to change the value of a prop, you’ll
get an error.
A function called changeProp increments the value of the local copy of the
prop and then logs it to the console.
Shows what happens when you run this component and click the change
myNumber button several times
Validating Incoming Props with PropTypes
When you invoke a JavaScript function and pass in arguments, the
function doesn’t care what type of data the arguments are, whether
they’re passed in at all, or whether more or fewer arguments are passed
in than the function defines.
The same things are true with props that you pass from a parent
component to a child component.
For programs to operate correctly, however, it often is important that
the props that are passed to a component are the same type of data that
the component is expecting.
React programmers (and programmers in general) must account for the
possibility of incorrect data types being passed to any function that
receives arguments.
But, it’s not always easy to figure out and detect possible data type
problems with a dynamically typed language such as JavaScript.
What Is PropTypes?
PropTypes is a tool for type checking and documenting props in React
components.
For each prop in your component, you can specify rules that the value
coming into the prop will be tested against.
If the prop value doesn’t pass those rules, a message will be displayed in
the JavaScript console in your browser.
PropTypes only displays these warning messages when you’re using the
development version of React.
Once your app is deployed and using the production version of React,
PropTypes is silent.
Validating that a prop is a string
With the PropType specified for firstName, when WelcomeMessage receives a
value of firstName that isn’t a string, a warning message will be displayed in
the console
Getting Started with PropTypes
npm install prop-types --save
Once PropTypes is installed, you’ll need to include the PropTypes library into
each component where you use it.
At the beginning of the file containing your component, use the following
import:
import PropTypes from 'prop-types;
Once imported, PropTypes works the same with both function and class
components, but where you place the PropTypes may differ
PropTypes inside a component’s body
Putting propTypes outside the class body
Using propTypes with a function component
What Can PropTypes Validate?
PropTypes can perform a wide variety of checks on a component’s props,
including the data type (as you’ve seen), whether required props are passed,
the shape of properties passed as objects, and more.
Validating Data Type
You’ve already seen how to check whether a prop is one of JavaScript’s data
types. The validators for JavaScript types are:
➤ [Link]
➤ [Link]
➤ [Link]
➤ [Link]
➤ [Link]
➤ [Link]
➤ [Link]
Validating Required Props
If a component requires a prop to be passed to it, you can indicate to
PropTypes that a prop is required by appending the isRequired validator to the
data type validator,
:Appending the isRequired validator
Validating Nodes
The node validator checks whether the prop’s value is something that can be
rendered.
React calls anything that can be rendered in a component a node.
The things that can be rendered in a component are numbers, strings,
elements, and arrays containing numbers, strings, or elements:
The node validator is useful in cases where you may not care whether the
value of the prop is a string or number or element, but you do care that it can
be rendered.
If one of your components does try to render a prop that isn’t a node, it will
cause your program to crash and display an error in the browser as well as in
the console even if you’re not using PropTypes.
You can view this default error message by trying to render a prop value that
isn’t a number, string, element, or an array of renderable data.
Figure shows the error message that displays when you try to render an object.
Notice that the error message doesn’t specify which prop caused the error, just
that there was one and the element in which it occurred.
Using [Link]
Validating React Elements
If you want to make sure that a prop is a React element, you can use
[Link].
You might use the element validator to test whether the children prop
contains an element
JavaScript Class Validation
[Link] tests that the supplied prop is an instance of a particular
JavaScript class (meaning that it has this class in its prototype chain).
Validating that a prop is an instance of a class
Limiting Props to Certain Values or Types
[Link] is a function that tests whether the value of a prop is one of
the specific items in a list. To use it, pass an array of possible values into the
oneOf function
Using [Link]
With the oneOfType validator, you can check whether the value of a prop is
one of a list of data types. To use it, pass an array containing the allowed data
types, using names of PropTypes’s data type validators:
Additional Validators
[Link] tests that the prop is an array in which each of the
elements matches a provided type:
[Link] tests that the prop is an object in which each of the
properties of the object match a provided type:
[Link] tests whether a prop value is an object containing specific
properties:
[Link] performs a strict object match on the prop, meaning that it
must include only the specified properties, each of which must pass its
validation:
Creating Custom PropTypes
If what you want to validate isn’t covered by any of the built-in validators, you
can create your own.
A custom validator is a function that will automatically receive three
arguments when it’s used:
➤ An object containing all of the props received by the component.
➤ The prop being tested.
➤ The name of the component.
In a custom prop, you can write the Error object that is returned when the
validation fails.
Using a custom validator to test for a phone number
Default Props
A component without default props
Setting defaults with the OR operator
Setting defaultProps as a static property
Setting defaultProps outside of the component body
REACT STATE
What Is state? In a React component, state is an object containing a set of
properties that may change over the lifetime of the component.
Changes to the properties in the state object control the behaviour and
updating of the component.
Initializing state
Initializing state is the process of defining the properties of the state object
and setting their initial values. The initial values are the values that will be used
for the first rendering of a component.
Initializing state in Class Components
There are a few important rules about initializing the state of a class
component:
1. The state object of a class component can have as many or as few properties
as you need.
2. Not all class components need to have state.
3. If your component does make use of state, you must initialize it.
4. The constructor function is the only place where you can change state
directly.
The reason for initializing the state object in the constructor function is that it’s
the first method to be called when you create an instance of a component. It is
possible to initialize the state object without a constructor function by using a
class property, which is also known as a public instance field, or a public field.
Initializing State in Function Components
The Difference between state and props
Props and state look similar at first glance:
➤ They’re both JavaScript objects.
➤ Changes to each of them cause components to update.
➤ Both are data that are used by a component to generate the HTML
output of the component
THE EVENT OBJECT
The Event object contains the properties and methods that are common to all
events. The most important of these base Event properties and methods are
the following:
➤ [Link] indicates whether an event can be cancelled. Cancelling an
event prevents the event from happening. Cancelling events is useful when
you want to prevent a user from clicking something or to prevent a form
element from submitting a form, for example.
➤ [Link] references the object onto which the event was originally
dispatched (such as an element that was clicked or a form input that was typed
into).
➤ [Link] contains the name of the event, such as click, change, load,
mouseover, and so forth.
➤ [Link] cancels an event if it’s cancellable.
Writing Inline Event Handlers
: 1. Inline event handlers aren’t reusable.
2. Inline event handlers can be difficult to read and they reduce the
organization of your code.
3. Inline event handlers are re-created every time the component re-renders.
In function com- ponents, this is what happens to all inner functions. But, in
class components, inline event handlers may affect performance, although the
effect is not likely to be noticeable, and prematurely optimizing your code for
this kind of problem before you have it will cause you more problems (in terms
of time wasted alone) than it solves.
Writing Event Handlers in Function Components
Writing Event Handlers in Class Components and Binding Event Handler
Functions