React チートシート(2021年6月更新版)

フォローしてね!: フォロー @EricTheCoder_


Reactを頻繁に使わないので、たとえ一番簡単なことをReactでやる時でも、ドキュメントやチュートリアルを見たり、フォーラムに質問を投稿したりする必要があります。

そのため、この記憶の助けとして、僕の記憶力がそれほど良くないので、Reactについて知っているすべての概念を一つの巨大な記憶の助けにすることにしました。

たまに読み返して、Reactについての知識を強化できるようにします。

アイデアやお勧めがあったら、コメント欄で遠慮なく教えてください。

React チートシート

Reactアプリの作成

// 新しいアプリを作成
npx create-react-app my-app-name

// 作成したアプリを実行
cd my-app-name
yarn start

// http://localhost:3000

最初のReact関数コンポーネント

  • React 17以降はReactを'import'する必要はありません
  • 最初の文字は大文字である必要があります
  • JSXを返さなければなりません

(src/App.js)

// Reactコンポーネント
function App(){
  return <h1>Hello World</h1>
} 

export default App;

このコンポーネントはどのようにブラウザにレンダリングされるのか?メインプロジェクトファイルはsrc/index.jsで、そのファイルにはコンポーネントをレンダリングする命令が含まれています。

ReactDOM.render(<App />, document.getElementById('root'))

Appコンポーネントは、public/index.htmlの'root' div内にレンダリングされます。

コンポーネントのインポート

コンポーネントは個別のファイルで作成されます。各コンポーネントはエクスポートされ、次にインポートする必要があります。

function Greeting(){
    return <h1>Hello World</h2>
}
export default Greeting

このコンポーネントをインポートしましょう。

import Greeting from './Gretting'

function App(){
    return <Greeting />
}

もしくは名前付きエクスポートです…

export function Greeting(){
    return <h1>Hello World</h2>
}

このコンポーネントをインポートしましょう。

import {Greeting} from './Gretting'

BEMネーミング規則

return (
<div className="app">
  <h1 className="app_title">Welcome to my application: {appTitle}</h1>
  <div className="product">
    <h1 className="product__name--large">Product name: {product.name}</h1>
    <h1 className="product__name--small">Nick name: {product.nickName}</h1>
    <p className="product__description">Product description: {product.description}
  </div>
<div>
)

JSXのルール

単一の要素を返す必要があります(親要素は一つだけ)

// 不正
return <h1>Hello world</h1><h2>Hi!</h2>

// 正しいフラグメント使用
return (
    <>
        <h1>Hello World</h1>
        <h2>Hi!</h2>
    </>
)
// 複数行をフォーマットするためのかっこに注意

classの代わりにclassNameを使用する
また、すべての属性名はキャメルケースである必要があります

// 不正
return (
    <div class="title">
        Hello World
    </div>
)

// 正しい
return (
    <div className="title">
    </div>
)

すべての要素を閉じる

return (
    <img src="http://example.com/image.jpg" />
    <input type="text" name="first_name" />
)

ネストされたコンポーネント

// アロー関数ショートハンドコンポーネント
const Person = () => <h1>Mike Taylor</h1>

// アロー関数コンポーネント
const Message = () => {
    return <h1>Hello</h1>
}

// 関数コンポーネント
function HelloWorld(){
  return (
      <>
          <Message />
          <Person />
      </>
  )
}

コンポーネントCSS

(src/App.css)

h1 {
    color: red;
}

(src/App.js)
CSSファイルをインポートする

import './App.css'

function App(){
  return <h1>Hello World</h1>
}

インラインCSS

function App(){
  return <h1 style={{ color: 'red' }}>Hello World</h1>
}

JSXの中のJavascript

  • {}で囲む必要があります
  • 式である必要があります(値を返す)
function App(){
    const name = 'Mike'
    return (
      <>
          <h1>Hello {name}</h1>
          <p>{name === 'Mike' ? '(admin)': '(user)'}</p>
      </>
    )
}

コンポーネントプロパティ(Props)

function App()
    return <Person name='Mike' age={29} />
}

const Person = (props) => {
    return <h1>Name: {props.name}, Age: {props.age}</h1>
}

// またはpropsオブジェクトの分解
const Person = ({name, age}) => {
    return <h1>Name: {name} Age: {age}</h1>
}

子プロパティ(スロット)

function App()
    return (
        <Person name='Mike' age={29}>
            こんにちは、これは歓迎メッセージです
        </Person>
    )
}

const Person = (props) => {
    return (
        <h1>Name: {props.name}, Age: {props.age}</h1>
        <p>{props.children}</p>
    )
}

// またはpropsオブジェクト分解
const Person = ({name, age, children}) => {
    return (
        <h1>Name: {name} Age: {age}</h1>
        <p>{children}</p>
    )
}

デフォルトPropsの値

const Person = ({name, age, children}) => {
    return (
        <h1>Name: {name} Age: {age}</h1>
        <p>{children}</p>
    )
}

Person.defaultProps = {
    name: 'No name',
    age: 0,
}

リスト

const people = [
  {id: 1, name: 'Mike', age: 29},
  {id: 2, name: 'Peter', age: 24},
  {id: 3, name: 'John', age: 39},
]
function App(){
    return (
        people.map(person => {
            return <Person name={person.name} age={person.age}/>
        })
    )
}

const Person = (props) => {
  return (
      <h1>Name: {props.name}, Age: {props.age}</h1>
  )
}

keyを使ったリスト(Reactの内部参照用)

function App(){
    return (
        people.map(person => {
            return <Person key={person.id} name={person.name} age={person.age}/>
        })
     )
}

Propsオブジェクト分解

function App(){
  return people.map(person => <Person key={person.id} {...person} />)
}

const Person = ({name, age}) => {
  return (
      <h1>Name: {name}, Age: {age}</h1>
  )
}

クリックイベント

const clickHandler = () => alert('Hello World')
function App(){
    return (
        <>
            <h1>私のアプリへようこそ</h1>
            <button onClick={clickHandler}>こんにちはと言う</button>
        </> 
    )
}

またはインラインで...

function App(){
    return (
        <>
            <h1>Welcome to my app</h1>
            <button onClick={ () => alert('Hello World') }>Say Hi</button>
        </>
     )
}

引数を渡すためにはアロー関数を使う必要があります。

const clickHandler = (message) => alert(message)
function App(){
    return (
        <>
            <h1>Welcome to my app</h1>
            <button onClick={() => clickHandler('Hello World')}>Say Hi</button>
        </> 
    )
}

eはイベント引数です。

const clickHandler = (e) => console.log(e.target)
function App(){
    return (
        <>
            <h1>Welcome to my app</h1>
            <button onClick={clickHandler}>Say Hi</button>
        </> 
    )
}

子供から親へのイベント渡し

function Todo({item, onDelete}) {
    return (
      <div>
        {item}
        <button onClick={() => onDelete(item)} 
      </div>
    )
}

function Todos() {
  const handleDelete = (todo) => {
    const newTodos = todos.filter(item => item !== todo)
    setTodos(() => newTodos)
  }

  return (
    {todos.map(todo => (
       <Todo item={todo} onDelete={handleDelete}/>
    }
  )
}

useStateフック

useStateの目的はリアクティブデータを扱うことです。アプリケーションで変更されるデータはすべて状態と呼ばれます。そして、状態が変わると、UIを更新するようにReactを動かしたいと思います。

  • フックは常に'use'プレフィックスで始まります
  • リアクトのコンポーネント/関数の中だけで呼び出す必要があります
  • 関数型コンポーネントのトップレベルで呼び出す必要があります
  • 条件付きで宣言を呼び出すことはできません
  • useStateは2つの配列を返します:[状態値、状態設定関数]
import React, {useState} from 'react';

const DisplayTitle = () => {
  const [title, setTitle] = useState('これがタイトルです')
  const handleClick = () => setTitle('新しいタイトル')
  return <>
    <h2>{title}</h2>
    <button type="button" className="btn" onClick={handleClick}>
      タイトルを変更
    </button>
  </>
};

export default DisplayTitle;

オブジェクトを使ったuseState

const DisplayTitle = () => {
  const [person, setPerson] = useState({name: 'Mike', age: 29})
  const handleClick = () => setPerson({...person, age: 35})
  return <>
    <h2>{title}</h2>
    <button type="button" className="btn" onClick={handleClick}>
      年齢を変更
    </button>
  </>
};

setStateの関数形式

function Counter() {
  const [count, setCount] = useState(0)
  // setStateを関数で使う
  const increase = () => setCount(() => count + 1)
  return (
    <>
      <h1>Counter</h1>
      <p>{count}</p>
      <button onClick={increase} className='btn'> + </button>
      <button onClick={() => setCount(() => count - 1)} className='btn'> - </button>
    </>
  )
}

useEffect

Reactでは、ライフサイクルイベントが発生した後や副作用が発生した後にコードを実行したいかもしれません。

デフォルトでは、useEffect関数は再レンダリングの後に実行されます。したがって、コンポーネントが更新されるたびにコードを実行することができます。

import React, { useEffect } from 'react';

function IncreaseValue() {
    const [value, setValue] = useState(0)
    useEffect(() => {
        document.title = `新しい値: ${value}` 
    })
    return <button onClick={() => setValue(value + 1)}>増加</button>
}

条件付きuseEffect

条件はuseEffect関数の中に置く必要があります。

useEffect(() => {
    if (value > 0) {
        document.title = `新しい値: ${value}` 
    }
})

useEffectの依存リスト

特定の状態が変わった時だけ、もしくは最初のレンダリング時にだけコードを実行したい場合はどうすればよいでしょうか?依存するパラメーターとして配列を送信し、useEffect関数を使用することができます。

状態が依存リストにある場合にのみuseEffectが実行されます。
リストが空[]の場合は、useEffectは初期レンダリング時にのみ実行されます。

useEffect(() => {
    document.title = `新しい値: ${value}` 
}, [])
// 空の配列に注目。useEffectは初期レンダリング時にのみ実行されます。

useEffect(() => {
    document.title = `新しい値: ${value}` 
}, [value])
// 'value'状態が変わるたびに実行されます。

useEffectクリーンアップ関数

コンポーネントがアンマウントされるたびにコードを実行したい場合はどうすればいいですか?

コンポーネントがUIから削除される前にだけ実行したいコードがある場合は、useEffect関数に'return'ステートメントを追加する必要があります。

useEffect(() =>  { 
    const timer = window.setInterval(() => { 
        setCount(count => count + 1)
    }, 1000)
    return () => clearInterval(timer)
}, [])

コード'clearInterval(timer)'は、コンポーネントがUIから削除される前(アンマウントする前)にだけ実行されます。

条件付きレンダリング

function DisplayGreeting() {
    const [name, setName] = useState('Mike')
    if (name === 'Mike') {
        return <h1>Hello admin {name}</h1> 
    }
    return <h1>Hello user {name}</h1> 
}

インラインIf-Else

  return (
    <div>
      ユーザーは<b>{isLoggedIn ? '現在' : 'いまはいない'}</b>ログインしています。
    </div>
  );
}

インライン論理的な&&オペレーター。
最初の式がtruthyな場合にのみ表示します。
truthy = 0, "", null, undefined, NaNではないもの

  function DisplayUserInfo({active}) {
    return (
      <div>
        { active && <h1>ユーザーはアクティブです</h1>}
      </div>
    );
}

複数のインラインIf

<span className={count === 0 && 'text-gray-500' || count > 0 && 'text-green-500' || count < 0 && 'text-red-500'}>{count}</span>

フォーム

const UserForm = () => {
  const [userName, setUserName] = useState('')
  const handleSubmit = (e) => {
    e.preventDefault()
   <br><br>こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。<br>[https://dev.to/ericchapman/react-cheat-sheet-updated-may-2021-1mcd](https://dev.to/ericchapman/react-cheat-sheet-updated-may-2021-1mcd)