React コンポーネント
目次
ステート
ステートの保持
※App.js
import React, {Component} from ‘react’;
class App extends Component {
style = {
fontSize: “20px”,
coloer: “red”,
}
constructor(props){
super(props);
this.state = {
msg: ‘Message from state.’,
}
}
render(){
return <div>
<p style={this.style}>{this.state.msg}</p>
<p style={this.style}>{this.props.msg}</p>
</div>;
}
}
export default App;
※index.js
import React from ‘react’;
import ReactDOM from ‘react-dom’;
import App from ‘./App’;
ReactDOM.render(
<React.StrictMode>
<App msg=”Message from prop” />
</React.StrictMode>,
document.getElementById(‘root’)
);
ステートの更新
import React, {Component} from ‘react’;
import ‘./App.css’;
class App extends Component {
style = {
fontSize: “20px”,
coloer: “red”,
}
constructor(props){
super();
this.state = {
counter: 0,
msg: ‘count start!’,
}
this.doAction = this.doAction.bind(this);
}
doAction(e){
this.setState((state)=>({
counter: state.counter + 1,
msg: `count:${state.counter}`,
}));
}
render(){
return <div>
<p style={this.style}>{this.state.msg}</p>
<button style={this.style} onClick={this.doAction}>Click</button>
</div>;
}
}
export default App;
コンテキスト
コンテキストの取得
import React, {Component} from ‘react’;
let data = {
title: ‘Title’,
message: ‘this is sample message’,
};
const SampleContext = React.createContext(data);
class App extends Component {
render(){
return <div>
<Title />
<Message />
</div>
}
}
class Title extends Component {
static contextType = SampleContext;
render(){
return <div>
{this.context.title}
</div>
}
}
class Message extends Component {
static contextType = SampleContext;
render(){
return <div>
{this.context.message}
</div>
}
}
export default App;
コンテキストの変更
import React, {Component} from ‘react’;
let data = {
title: ‘Title’,
message: ‘this is sample message’,
};
const SampleContext = React.createContext(data);
class App extends Component {
newData = {
title: ‘Title_changed’,
message: ‘Message_changed’,
};
render(){
return <div>
<Title />
<Message />
↓ の部分のみ、contextにdataではなくnewDataを使用
<SampleContext.Provider value={this.newData}>
<Title />
<Message />
</SampleContext.Provider>
<Title />
<Message />
</div>
}
}
class Title extends Component {
static contextType = SampleContext;
~
}
class Message extends Component {
static contextType = SampleContext;
~
}
export default App;
Hooks
useState
import React, { useState } from ‘react’
const [変数, set関数名] = useState(初期値);
例
const [count, setCount] = useState(0);
const [value, setValue] = useState(‘AAA’); 等
return (
clickの度に+1された値がcountにセットされる
<div onClick={()=>setCount(count+1)}>
{count}
</div>
);
useMemo
import React, { useMemo } from ‘react’
const App = () => {
const 変数 = useMemo(() => 関数名, []);
heavyFuncはAppを何度呼び出しても最初の1回しか実行されず、常に1回目の実行結果がキャッシュされて使用される
const result = useMemo(() => heavyFunc(), []);
return (
<div>
{result}
</div>
);
}
useEffect
import React, { useEffect } from ‘react’
const App = () => {
レンダリング前だと要素を取得できない
const elm = document.querySelector(‘#message’);
console.log(elm); // null
関数の実行タイミングをReactのレンダリング後まで遅らせる
useEffect(() => {
const elm = document.querySelector(‘#message‘);
console.log(elm); // HTMLDivElement
elm.innerHTML = ‘REACT’;
});
return <div id=”message“></div>;
}
export default App;
コンポーネント
関数コンポーネント
let dom = document.querySelector(‘#root’);
let style = {
fontSize: “20pt”,
color: “red”,
};
関数コンポーネントの定義
function Func(props){
return <p style={style}>{props.content} {props.name}</p>;
}
let element = (
<div>
関数コンポーネントの呼び出し
<Func content=”Function” name=”React” />
</div>
);
ReactDOM.render(element, dom);
コンポーネントクラス
let dom = document.querySelector(‘#root’);
let style = {
fontSize: “20pt”,
color: “red”,
};
class Func extends React.Component {
content = ”;
name = ”;
constructor(props){
super(props);
this.content = props.content;
this.name = props.name;
}
render(){
return <p style={style}>{this.content} {this.name}</p>;
↓も可
return <p style={style}>{this.props.content} {this.props.name}</p>;
}
}
let element = (
<div>
<Func content=”Function” name=”React” />
</div>
);
ReactDOM.render(element, dom);
連携
import React, {Component} from ‘react’;
{Component}までimportしているのでReact.は省略できる
class App extends Component {
data = [
”PHP”,
”Python”,
”Ruby”,
];
render(){
return <div>
<List title=”サンプルリスト” data={this.data} />
</div>
}
}
class List extends Component {
number = 1;
render(){
return (
<div>
<p>{this.props.title}</p>
<ul>
{this.props.data.map(
(item)=>
<Item number={this.number++} value={item} key={this.number} />
)}
</ul>
</div>
);
}
}
class Item extends Component {
render(){
return (
<li>
[{this.props.number}]{this.props.value}
</li>
);
}
}
export default App;
子コンポーネントのエレメントを取得
class App extends Component {
render(){
return <div>
<h1>React</h1>
<Message title=”Children”>
1行目.2行目.3行目
</Message>
</div>
}
}
class Message extends Component{
render(){
let content = this.props.children;
return <div>
{content}
</div>
}
}
export default App;
フォーム利用
import React, {Component} from ‘react’;
class App extends Component {
input = ”;
constructor(props){
super(props);
this.state = {
message: ‘type your name:’
};
this.doChange = this.doChange.bind(this);
this.doSubmit = this.doSubmit.bind(this);
}
doChange(event){
フォームの値を取得
this.input = event.target.value;
}
doSubmit(event){
this.setState({
message: `Hello, ${this.input}!!`
});
フォームデータの送信をクライアント側で止める
event.preventDefault();
}
render(){
return <div>
<h2>{this.state.message}</h2>
<form onSubmit={this.doSubmit}>
<input type=”text”
onChange={this.doChange}
必須属性
required
正規表現による入力制限
pattern=”A-Za-z”
最小値
min=”10″
最大値
max=”100″ />
最小文字数
minlength=”10″
最大文字数
maxlength=”100″ />
<input type=”submit” value=”Click” />
</form>
</div>
}
}
export default App;
フォームの自作チェック
import React, {Component} from ‘react’;
class App extends Component {
constructor(props){
super(props);
this.state = {
message: ‘type your name:’
};
this.doCheck = this.doCheck.bind(this);
}
doCheck(event){
alert(`${event.target.value}は入力最大文字数を超過しています(最大10文字)`);
}
render(){
return <div>
<h2>{this.state.message}</h2>
チェックイベントに自作クラスを指定
<Message maxlength=”10″ onCheck={this.doCheck} />
</div>
}
}
class Message extends Component {
constructor(props){
super(props);
this.doChange = this.doChange.bind(this);
}
doChange(e){
if (e.target.value.length > this.props.maxlength) {
チェックイベントを発生させる=doCheckが実行される
this.props.onCheck(e);
e.target.value = e.target.value.substr(0, this.props.maxlength);
}
}
render(){
return <div>
<input type=”text” onChange={this.doChange} />
</div>
}
}
export default App;
コンテキストを利用したテーマの統一
import React, {Component} from ‘react’;
let theme = {
light: {
backgroundColor: “pink”,
},
dark: {
backgroundColor: “gray”,
}
};
const ThemeContext = React.createContext(theme.dark);
class App extends Component {
static contextType = ThemeContext;
render(){
return <div style={this.context}>
<Title title=”Title” />
<Message message=”Message” />
</div>
}
}
class Title extends Component {
static contextType = ThemeContext;
render(){
return <div style={this.context}>
{this.props.title}
</div>
}
}
class Message extends Component {
static contextType = ThemeContext;
render(){
return <div style={this.context}>
{this.props.message}
</div>
}
}
export default App;