21
loading...
This website collects cookies to deliver better user experience
state
, props
and render
looks like:class Hello extends React.Component {
constructor(props) {
super(props);
this.state = {
name: props.name
};
}
render() {
return <h1>Hello, {this.state.name}</h1>;
}
}
// Render
ReactDOM.render(
Hello,
document.getElementById('root')
);
<div>
somewhere in your HTML file:<div id="root"></div>
element
in the place of the div
with root
id
like this:const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
Hello.jsx
import React, { Component } from 'react';
class Hello extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
export default Hello;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import Hello from './app/Hello.jsx';
ReactDOM.render(<Hello />, document.getElementById('root'));
"Rendering" is any time a function component gets called (or a class-based render method gets called) which returns a set of instructions for creating DOM.
"Mounting" is when React "renders" the component for the first time and actually builds the initial DOM from those instructions.
constructor
:class Hello extends React.Component {
constructor() {
this.state = {
endOfMessage: '!'
};
}
render() {
return <h1>Hello, {this.props.name} {this.state.endOfMessage}</h1>;
}
}
this.state.comment = 'Hello'; // Don't do this
setState()
method:this.setState({comment: 'Hello'});
setState
is asynchronous, we should take into account the previous state:this.setState(function(prevState, prevProps) {
return {
counter: prevState.counter + prevProps.increment
};
});
this.setState(prevState => ({
...prevState,
someProperty: {
...prevState.someProperty,
someOtherProperty: {
...prevState.someProperty.someOtherProperty,
anotherProperty: {
...prevState.someProperty.someOtherProperty.anotherProperty,
flag: false
}
}
}
}))
[immutability-helper](https://github.com/kolodny/immutability-helper)
package is recommended.> b = {item1: 'a', item2: {subItem1: 'y', subItem2: 'z'}}
//-> { item1: 'a', item2: {subItem1: 'y', subItem2: 'z'}}
> b.item2 = {...b.item2, subItem1: 'modified'}
//-> { subItem1: 'modified', subItem2: 'z' }
> b
//-> { item1: 'a', item2: { subItem1: 'modified', subItem2: 'z' } }
> b.item2 = {subItem1: 'modified'} // Not OK
//-> { subItem1: 'modified' }
> b
//-> { item1: 'a', item2: { subItem1: 'modified' } }
props
in the constructor
, we need to call the parent class constructor by using super(props)
:class Button extends React.Component {
constructor(props) {
super(props);
console.log(props);
console.log(this.props);
}
// ...
}
props
to set an initial state is an anti-pattern of React. In the past, we could have used the componentWillReceiveProps
method to do so, but now it's deprecated.class Hello extends React.Component {
constructor(props) {
super(props);
this.state = {
property: this.props.name, // Not recommended, but OK if it's just used as seed data.
};
}
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
props
to initialise a state
is not an anti-patter if we make it clear that the prop
is only used as seed data for the component's internally-controlled state.hooks
; they have lifecycle methods instead.render()
componentDidMount()
componentDidUpdate()
componentWillUnmount()
shouldComponentUpdate()
static getDerivedStateFromProps()
getSnapshotBeforeUpdate()
props
, state
and render
:function Welcome(props) {
const [timeOfDay, setTimeOfDay] = useState('morning');
return <h1>Hello, {props.name}, good {timeOfDay}</h1>;
}
// or
const Welcome = (props) => {
const [timeOfDay, setTimeOfDay] = useState('morning');
return <h1>Hello, {props.name}, good {timeOfDay}</h1>;
}
// Render
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
useState
hook to that array, initialising the state in the process:import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useState
hook is the way function components allow us to use a component's state
in a similar manner as this.state
is used in class components.What is a Hook? A Hook is a special function that lets you “hook into” React features. For example, useState
is a Hook that lets you add React state to function components. We’ll learn other Hooks later.
When would I use a Hook? If you write a function component and realize you need to add some state to it, previously you had to convert it to a class. Now you can use a Hook inside the existing function component.
useState
in the function declaration (count
in our example).<p>You clicked {count} times</p>
<p>You clicked {this.state.count} times</p>
setCount
in this case) with the values of the new state.<button onClick={() => setCount(count + 1)}>
Click me
</button>
this
keyword followed by the state
and the property to be updated:<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
props
in function components is pretty straight forward: we just pass them as the component argument:function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}