Day 2 - June 28, 2022
Topics Covered
- Working with component state
- Working with component properties
- Passing data from parent to child components
- Lifecycle methods
- Functional components
Component state and properties
Components are useless unless they display or use data in some meaningful way. We will set some initial data so that our components can render the initial view. As data changes, React can track those changes and automatically update the UI. We will refer to each snapshot of the data as the component state. Whenever we tell a React component to change its state, the component will automatically re-render itself. The component state can be controlled by the component itself or by code that exists outside of the component itself.
Properties (or Attributes) are used to pass data into components. We will pass data to our components properties by modifying the JSX. Properties are different than state because they are typically set during the initial render but remain unchanged afterward. If a property is changed, then the component will need to be re-rendered to keep the display in sync. It is typically a parent component that decides when to re-render the component.
Working with component state
If your component uses state, you should remember to set some initial data. Doing so will prevent render failures due to having unexpected or missing state values. When setting the state, we can simply pass a JavaScript object to the component. The object properties can be used to initialize the data.
We have set the initial state and safely rendered the component. What about updating the state after the
component has already been rendered? In the example below, a component is rendered with the initial
state. After three seconds, the state object is replaced by calling setState()
. React will
automatically detect the change of state and force the component to re-render itself.
In the example above, the state object was replaced with a new object. Instead of replacing the entire state object each time, we can change single properties instead (leaving the rest of the state as it was).
Working with component properties
In React, properties are like state, they allow you to pass data into components. Unlike state, properties are usually only set once, when the component is rendered. Setting property values is slightly different than when working with state values.
- Immutable
- An object or value that cannot be changed.
In the example, we are setting the default property values for a component. Notice the "static" keyword. The default properties are not instance variables as with component state. This is because properties are immutable so there is no need for them to be kept as instance variables.
Properties would be more useful if we could set them for each instance of a component directly in the JSX. Below you will find the revised App() function illustrating how the property value can be changed rather than using the default values. We can pass any valid JavaScript expression in the JSX.
Passing data from parent to child components
Combining much of the content learned, we are initializing state and passing property data to child components from a parent component.
Lifecycle methods
React components have a life cycle in which the framework executes various functions in a specific
order. In fact, the render()
function is a lifecycle method used to return the content to
be rendered by a component.
There are two main lifecycle flows in React. The first happens when the component is initially rendered. The second happens whenever the component is updated.
Initial Render
getDerivedStateFromProps()
render()
componentDidMount()
componentWillUnmount()
Update
getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
componentWillUnmount()
- componentDidMount
- This is called after the component is mounted. This method can be used to perform initialization work such as fetching data.
- componentDidUpdate
- This is called when the component is updated. In most cases you will not need handle this event.
- componentWillUnmount
- Called when a component is about to be removed. Gives an opportunity to cancel any pending asyncronous requests.
- getDerivedStateFromProps
- Called when the component is first rendered or if a new property value is received. Allows you to update the state of the component based on property values.
- getSnapshotBeforeUpdate
-
Allows you to manipulate the rendered content before it is actually presented. Unlike
render()
, this method runs syncronously. - render
-
Returns the content to be rendered by the component. The method is called when the component
is
first mounted, if a property value is received, or when
setState()
is called. - shouldComponentUpdate
-
Called before
render()
, this method allows you to decide whether the component should re-render. Returntrue
to allow rendering otherwise returnfalse
.
Functional components
So far, the code examples you've seen all use classes that extend the Component
class.
Sometimes programmers prefer to use functional components instead. Functional
components are usually easier to read and require less coding but they do not store state or execute
lifecycle methods.
In the example above, you can see that we have written MyComponent
using a function instead
of a class. The code is much more concise and easier to read. As you study the code example, you will
notice that:
-
MyComponent()
function is a pure function. - The function is written using arrow function syntax. This is a convention of React however it is perfectly find to declare function using traditional JavaScript function syntax.
- Functional components are stateless.
Let's rewrite the component again, this time we will introduce properties. Since our component is a
function, we can no longer use the this
keyword. Instead, our function will accept a
new parameter props
that will contain each property value, similar to the class way, that
is this.props.propName
.
Default properties are also available with functional components.