Step 11
We can now generate the cycles but we need to reload (re-render) the Output
component to show the new cycles.
This is where "states" come in!
We learned that props refer to data passed from parent components to child components.
The props represent "read-only" data that are meant to be immutable.
So if you are a component, should not modify props that you receive!
A component's state, on the other hand, represents mutable data. The "state" ultimately affects what is rendered on the page.
A component's state is managed internally by the component itself and is meant to change over time, commonly due to user input (e.g., clicking on a button on the page).
By having a component manage its own state, any time there are changes made to that state, React will know and automatically make the necessary updates to the page.
This is one of the key benefits of using React to build UI components:
When it comes to re-rendering the page, we just have to think about updating state.
- We don't have to keep track of exactly which parts of the page changed each time there are updates.
- We don't need to decide how we will efficiently re-render the page.
- React compares the previous state and new state, determines what has changed, and makes these decisions for us.
- This process of determining what has changed in the previous and new states is called Reconciliation.
Update the constructor of App
component:
constructor(props) {
super(props);
this.state = {
cycles: [
"11:44 PM",
"1:14 AM",
"2:44 AM",
"4:14 AM",
"5:44 AM",
"7:14 AM",
],
};
}
When you update the state, you must use the function setState
(which is inherited from Component
class).
We can technically update the
state
directly, but that way React will not know we have updated it!
The simplest way to use setState
is to pass an object to it, and the object will be merged into the current state to form the new state.
this.setState({ cycles: [/* new values */] })
Let's update the calcCycles
method to update the state:
calcCycles() {
// get current time
let now = Date.now(); // in milliseconds
let minute = 60 * 1000; // milliseconds
let cycle = now;
const cycles = new Array(this.state.cycles.length);
// allow 14 minutes to fall sleep
cycle += 14 * minute;
// calculate 6 sleep cycles (each 90 minutes)
for (let i = 0; i < 6; i++) {
cycle += 90 * minute;
// update the sleep cycles
cycles[i] = new Date(cycle).toLocaleTimeString([], {
hour: "2-digit",
minute: "2-digit",
});
}
// print cycles for sanity check
console.log(cycles);
// update state
this.setState({ cycles: cycles });
};
Aside: Don't forget to update the props passed to Output
component:
- <Output cycles={this.cycles} />
+ <Output cycles={this.state.cycles} />
Save the file and reload the app. Click on the zzz
button. The cycles must be updated in the page!