Reactクラスコンポーネント
React 16.8以前は、クラスコンポーネントは、Reactコンポーネントの状態とライフサイクルを追跡する唯一の方法でした。機能コンポーネントは「ステートレス」と見なされました。
フックが追加されたことで、関数コンポーネントはクラスコンポーネントとほぼ同等になりました。違いはごくわずかなので、ReactでClassコンポーネントを使用する必要はおそらくないでしょう。
関数コンポーネントが優先されますが、Reactからクラスコンポーネントを削除する計画は現在ありません。
このセクションでは、Reactでクラスコンポーネントを使用する方法の概要を説明します。
このセクションをスキップして、代わりに関数コンポーネントを使用してください。
コンポーネントを反応させる
コンポーネントは、独立した再利用可能なコードビットです。これらはJavaScript関数と同じ目的を果たしますが、単独で機能し、render()関数を介してHTMLを返します。
コンポーネントには、クラスコンポーネントと関数コンポーネントの2つのタイプがあります。この章では、クラスコンポーネントについて学習します。
クラスコンポーネントを作成する
Reactコンポーネントを作成する場合、コンポーネントの名前は大文字で始める必要があります。
コンポーネントにはextends React.Component
ステートメントを含める必要があります。このステートメントはReact.Componentへの継承を作成し、コンポーネントにReact.Componentの関数へのアクセスを許可します。
コンポーネントにはrender()
メソッドも必要です。このメソッドはHTMLを返します。
例
と呼ばれるクラスコンポーネントを作成しますCar
class Car extends React.Component {
render() {
return <h2>Hi, I am a Car!</h2>;
}
}
これで、ReactアプリケーションにCarというコンポーネントがあり、
<h2>
要素を返します。
アプリケーションでこのコンポーネントを使用するには、通常のHTMLと同様の構文を使用します。
<Car />
例
Car
「ルート」要素にコンポーネントを表示します。
ReactDOM.render(<Car />, document.getElementById('root'));
コンポーネントコンストラクタ
コンポーネントに関数がある場合
、この関数はコンポーネントが開始されたときに呼び出されます。constructor()
コンストラクター関数は、コンポーネントのプロパティを開始する場所です。
Reactでは、コンポーネントのプロパティは。というオブジェクトに保持する必要があります
state
。
詳細についてstate
は、このチュートリアルの後半で学習します。
コンストラクター関数は、親コンポーネントのコンストラクター関数を実行するステートメントを含めることによって親コンポーネントの継承を尊重する場所でもあり、コンポーネントsuper()
は親コンポーネントのすべての関数にアクセスできます(React.Component
)。
例
Carコンポーネントにコンストラクター関数を作成し、colorプロパティを追加します。
class Car extends React.Component {
constructor() {
super();
this.state = {color: "red"};
}
render() {
return <h2>I am a Car!</h2>;
}
}
render()関数でcolorプロパティを使用します。
例
class Car extends React.Component {
constructor() {
super();
this.state = {color: "red"};
}
render() {
return <h2>I am a {this.state.color} Car!</h2>;
}
}
小道具
コンポーネントのプロパティを処理する別の方法は、を使用することprops
です。
小道具は関数の引数のようなものであり、属性としてコンポーネントに送信します。
詳細についてprops
は、次の章で説明します。
例
属性を使用してCarコンポーネントに色を渡し、render()関数で使用します。
class Car extends React.Component {
render() {
return <h2>I am a {this.props.color} Car!</h2>;
}
}
ReactDOM.render(<Car color="red"/>, document.getElementById('root'));
コンストラクターの小道具
コンポーネントにコンストラクター関数がある場合、propsは常にコンストラクターに渡され、super()
メソッドを介してReact.Componentにも渡される必要があります。
例
class Car extends React.Component {
constructor(props) {
super(props);
}
render() {
return <h2>I am a {this.props.model}!</h2>;
}
}
ReactDOM.render(<Car model="Mustang"/>, document.getElementById('root'));
コンポーネント内のコンポーネント
他のコンポーネント内のコンポーネントを参照できます。
例
ガレージコンポーネント内のCarコンポーネントを使用します。
class Car extends React.Component {
render() {
return <h2>I am a Car!</h2>;
}
}
class Garage extends React.Component {
render() {
return (
<div>
<h1>Who lives in my Garage?</h1>
<Car />
</div>
);
}
}
ReactDOM.render(<Garage />, document.getElementById('root'));
ファイル内のコンポーネント
Reactはコードを再利用することであり、コンポーネントの一部を別々のファイルに挿入するのが賢明です。
これを行うには、ファイル拡張子を付けて新しいファイルを作成し、その.js
中にコードを配置します。
ファイルは(以前のように)Reactをインポートすることで開始する必要があり、ステートメントで終了する必要があることに注意してくださいexport default Car;
。
例
これは新しいファイルで、名前を付けましたCar.js
:
import React from 'react';
class Car extends React.Component {
render() {
return <h2>Hi, I am a Car!</h2>;
}
}
export default Car;
コンポーネントを使用できるようにするにCar
は、アプリケーションにファイルをインポートする必要があります。
例
Car.js
これで、ファイルをアプリケーションに
インポートし、Car
ここで作成されたかのようにコンポーネントを使用できます。
import React from 'react';
import ReactDOM from 'react-dom';
import Car from './Car.js';
ReactDOM.render(<Car />, document.getElementById('root'));
Reactクラスコンポーネントの状態
Reactクラスコンポーネントには組み込みのstate
オブジェクトがあります。
state
先ほどコンポーネントコンストラクターのセクションで使用したことに気づいたかもしれません。
state
オブジェクトは、コンポーネントに属するプロパティ値を格納する場所です。
オブジェクトが変更されるstate
と、コンポーネントは再レンダリングされます。
状態オブジェクトの作成
状態オブジェクトはコンストラクターで初期化されます。
例
state
コンストラクターメソッドでオブジェクトを指定します。
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {brand: "Ford"};
}
render() {
return (
<div>
<h1>My Car</h1>
</div>
);
}
}
状態オブジェクトには、必要な数のプロパティを含めることができます。
例
コンポーネントに必要なすべてのプロパティを指定します。
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {
brand: "Ford",
model: "Mustang",
color: "red",
year: 1964
};
}
render() {
return (
<div>
<h1>My Car</h1>
</div>
);
}
}
state
オブジェクトの使用
次の構文state
を使用して、コンポーネント内の任意の場所でオブジェクト
を参照します。this.state.propertyname
例:
メソッドstate
内のオブジェクトを
参照してください。render()
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {
brand: "Ford",
model: "Mustang",
color: "red",
year: 1964
};
}
render() {
return (
<div>
<h1>My {this.state.brand}</h1>
<p>
It is a {this.state.color}
{this.state.model}
from {this.state.year}.
</p>
</div>
);
}
}
state
オブジェクトの変更
状態オブジェクトの値を変更するには、this.setState()
メソッドを使用します。
オブジェクトの値がstate
変更されると、コンポーネントが再レンダリングされます。つまり、出力は新しい値に応じて変更されます。
例:
onClick
colorプロパティを変更するイベントを含むボタンを追加します。
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {
brand: "Ford",
model: "Mustang",
color: "red",
year: 1964
};
}
changeColor = () => {
this.setState({color: "blue"});
}
render() {
return (
<div>
<h1>My {this.state.brand}</h1>
<p>
It is a {this.state.color}
{this.state.model}
from {this.state.year}.
</p>
<button
type="button"
onClick={this.changeColor}
>Change color</button>
</div>
);
}
}
常にsetState()
メソッドを使用して状態オブジェクトを変更します。これにより、コンポーネントが更新されたことを確認し、render()メソッド(および他のすべてのライフサイクルメソッド)を呼び出します。
コンポーネントのライフサイクル
Reactの各コンポーネントには、3つの主要なフェーズで監視および操作できるライフサイクルがあります。
3つのフェーズは、マウント、更新、および アンマウントです。
実装
マウントとは、要素をDOMに配置することを意味します。
Reactには、コンポーネントをマウントするときにこの順序で呼び出される4つの組み込みメソッドがあります。
constructor()
getDerivedStateFromProps()
render()
componentDidMount()
メソッドは必須であり、render()
常に呼び出されます。その他はオプションであり、定義すると呼び出されます。
constructor
このconstructor()
メソッドは、コンポーネントが開始されるときに何よりも先に呼び出され、state
初期値やその他の初期値を設定するのに自然な場所です。
constructor()
メソッドは
props
引数として、を使用して呼び出されます。常に何よりも前に呼び出すことから始める必要があります。super(props)
これにより、親のコンストラクターメソッドが開始され、コンポーネントがその親(React.Component
)からメソッドを継承できるようになります。
例:
このconstructor
メソッドは、コンポーネントを作成するたびにReactによって呼び出されます。
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
render() {
return (
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
getDerivedStateFromProps
このgetDerivedStateFromProps()
メソッドは、DOMで要素をレンダリングする直前に呼び出されます。
state
これは、イニシャルに基づいてオブジェクトを
設定するための自然な場所props
です。
It takes
state
as an argument, and returns an object with changes to the
state
.
The example below starts with the favorite color being
"red", but the
getDerivedStateFromProps()
method updates the favorite color based on the
favcol
attribute:
Example:
The getDerivedStateFromProps
method is called
right before the render method:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
static getDerivedStateFromProps(props, state) {
return {favoritecolor: props.favcol };
}
render() {
return (
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
);
}
}
ReactDOM.render(<Header favcol="yellow"/>, document.getElementById('root'));
render
The render()
method is required, and is the
method that actually outputs the HTML to the DOM.
Example:
A simple component with a simple render()
method:
class Header extends React.Component {
render() {
return (
<h1>This is the content of the Header component</h1>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
componentDidMount
The componentDidMount()
method is called after the
component is rendered.
This is where you run statements that requires that the component is already placed in the DOM.
Example:
At first my favorite color is red, but give me a second, and it is yellow instead:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
componentDidMount() {
setTimeout(() => {
this.setState({favoritecolor: "yellow"})
}, 1000)
}
render() {
return (
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Updating
The next phase in the lifecycle is when a component is updated.
A component is updated whenever there is a change in the component's
state
or props
.
React has five built-in methods that gets called, in this order, when a component is updated:
getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
The render()
method is required and will
always be called, the others are optional and will be called if you define them.
getDerivedStateFromProps
Also at updates the getDerivedStateFromProps
method is
called. This is the first method that is called when a component gets updated.
This is still the natural place to set the state
object based on the initial props.
The example below has a button that changes the favorite color to blue, but
since the getDerivedStateFromProps()
method is called,
which updates the state with the color from the favcol attribute, the favorite color is
still
rendered as yellow:
Example:
If the component gets updated, the getDerivedStateFromProps()
method is called:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
static getDerivedStateFromProps(props, state) {
return {favoritecolor: props.favcol };
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header favcol="yellow"/>, document.getElementById('root'));
shouldComponentUpdate
In the shouldComponentUpdate()
method
you can return a Boolean value that specifies whether React should continue with the rendering or not.
The default value is true
.
The example below shows what happens when the
shouldComponentUpdate()
method returns false
:
Example:
Stop the component from rendering at any update:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
shouldComponentUpdate() {
return false;
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Example:
Same example as above, but this time the shouldComponentUpdate()
method returns
true
instead:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
shouldComponentUpdate() {
return true;
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
render
The render()
method is of course called when a component gets updated,
it has to re-render the HTML to the DOM, with the new changes.
The example below has a button that changes the favorite color to blue:
Example:
Click the button to make a change in the component's state:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
changeColor = () => {
this.setState({favoritecolor: "blue"});
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<button type="button" onClick={this.changeColor}>Change color</button>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
getSnapshotBeforeUpdate
In the getSnapshotBeforeUpdate()
method
you have access to the props
and
state
before the update, meaning that
even after the update, you can check what the values were before the
update.
If the getSnapshotBeforeUpdate()
method
is present, you should also include the
componentDidUpdate()
method, otherwise you will get an error.
The example below might seem complicated, but all it does is this:
When the component is mounting it is rendered with the favorite color "red".
When the component has been mounted, a timer changes the state, and after one second, the favorite color becomes "yellow".
This action triggers the update phase, and since this component has a
getSnapshotBeforeUpdate()
method, this method is executed, and writes a
message to the empty DIV1 element.
Then the componentDidUpdate()
method is
executed and writes a message in the empty DIV2 element:
Example:
Use the
getSnapshotBeforeUpdate()
method to find out
what the state
object looked like before
the update:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
componentDidMount() {
setTimeout(() => {
this.setState({favoritecolor: "yellow"})
}, 1000)
}
getSnapshotBeforeUpdate(prevProps, prevState) {
document.getElementById("div1").innerHTML =
"Before the update, the favorite was " + prevState.favoritecolor;
}
componentDidUpdate() {
document.getElementById("div2").innerHTML =
"The updated favorite is " + this.state.favoritecolor;
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<div id="div1"></div>
<div id="div2"></div>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
componentDidUpdate
The componentDidUpdate
method
is called after the component is updated in the DOM.
The example below might seem complicated, but all it does is this:
When the component is mounting it is rendered with the favorite color "red".
When the component has been mounted, a timer changes the state, and the color becomes "yellow".
This action triggers the update phase, and since this component has
a componentDidUpdate
method, this method is
executed and writes a message in the empty DIV element:
Example:
The componentDidUpdate
method is called
after the update has been rendered in the DOM:
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {favoritecolor: "red"};
}
componentDidMount() {
setTimeout(() => {
this.setState({favoritecolor: "yellow"})
}, 1000)
}
componentDidUpdate() {
document.getElementById("mydiv").innerHTML =
"The updated favorite is " + this.state.favoritecolor;
}
render() {
return (
<div>
<h1>My Favorite Color is {this.state.favoritecolor}</h1>
<div id="mydiv"></div>
</div>
);
}
}
ReactDOM.render(<Header />, document.getElementById('root'));
Unmounting
The next phase in the lifecycle is when a component is removed from the DOM, or unmounting as React likes to call it.
React has only one built-in method that gets called when a component is unmounted:
componentWillUnmount()
componentWillUnmount
The componentWillUnmount
method is
called when the component is about to be removed from the DOM.
Example:
Click the button to delete the header:
class Container extends React.Component {
constructor(props) {
super(props);
this.state = {show: true};
}
delHeader = () => {
this.setState({show: false});
}
render() {
let myheader;
if (this.state.show) {
myheader = <Child />;
};
return (
<div>
{myheader}
<button type="button" onClick={this.delHeader}>Delete Header</button>
</div>
);
}
}
class Child extends React.Component {
componentWillUnmount() {
alert("The component named Header is about to be unmounted.");
}
render() {
return (
<h1>Hello World!</h1>
);
}
}
ReactDOM.render(<Container />, document.getElementById('root'));