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;