React: States and Lifecycle methods
States
- only usable with class components
- can be confused with Properties
- state is a JS object that contains data relevant to a components
- updating
state
on a component causes the component to (almost) instantly rerender - state must be initialized when a component is created
- state can only be updated using the function
setState
src/index.js
/ Import the React and ReactDOM libraries
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
constructor(props) {
super(props); //we must call constructor of React.Component
this.state = { lat: null, errorMessage: '' }; // initialize state of lat, we dont know value of lat yet, so it is null
window.navigator.geolocation.getCurrentPosition(
position => {
this.setState({ lat: position.cords.latitude })
},
err => {
this.setState({ errorMessage: err.message });
}
);
}
render() {
if (this.state.errorMessage && !this.state.lat) {
return (
<div>Error: {this.state.errorMessage}</div>
);
}
if (!this.state.errorMessage && this.state.lat) {
return (
<div>Latitude: {this.state.lat}</div>
);
}
return <div>Loading!</div>
}
}
// Take the react component and show it on the screen
ReactDOM.render(
<App />,
document.querySelector('#root')
);
Lifecycle methods
constructor - good place to do one-time setup
render - avoid doing anything besides returning JSX
componentDidMount - good place to data-loading
componenDidUpdate - good place to do more data-loading when state/props change
componentWillUnmount - good place to do cleanup (especially for non-React stuff
See that we are not using contructor
in following code. The result is the same, as code is transformed by Babel, which will add constructor
automatically.
src/index.js
/ Import the React and ReactDOM libraries
import React from 'react';
import ReactDOM from 'react-dom';
import SeasonDisplay from './SeasonDisplay';
class App extends React.Component {
state = { lat: null, errorMessage: '' };
componentDidMount() {
window.navigator.geolocation.getCurrentPosition(
position => {
this.setState({ lat: position.cords.latitude });
},
err => {
this.setState({ errorMessage: err.message });
}
);
}
componentDidUpdate() {
}
renderContent() {
if (this.state.errorMessage && !this.state.lat) {
return (
<div>Error: {this.state.errorMessage}</div>
);
}
if (!this.state.errorMessage && this.state.lat) {
return (
<SeasonDisplay lat={this.state.lat} />
);
}
return <div>Loading!</div>
}
render() {
return (
<div className="border end">
{this.renderContent()}
</div>
);
}
}
// Take the react component and show it on the screen
ReactDOM.render(
<App />,
document.querySelector('#root')
);
src/SeasonDisplay.js
import './SeasonDisplay.css';
import React from 'react';
const getSeason = (lat, month) => {
if (month > 2 && month < 9) {
return lat > 0 ? 'summer' : 'winter';
} else {
return lat > 0 ? 'winter' : 'summer';
}
}
const SeasonDisplay = (props) => {
const season = getSeason(props.lat, new Date().getMonth());
const text = season === 'winter' ? 'Burr, it is chilly' : 'Lets hit the beach';
return (
<div>
{text}
</div>
);
};
export default SeasonDisplay;