序章

React は、アプリケーションのインタラクティブなユーザーインターフェイスを作成するために使用できるフロントエンドJavaScriptライブラリです。

このチュートリアルでは、ToDoアプリケーションを作成します。 アプリケーションは、タスクを表示し、新しいタスクを追加し、タスクを完了としてマークし、タスクを削除する必要があります。 これらのアクションは、 CRUD(作成、読み取り、更新、および削除)アプリケーションの4つの側面に触れます。

このタイプのプロジェクトは、多くの場合、クラスコンポーネントを使用して実行されますが、このアプリケーションは、代わりに ReactHooksを統合します。 React Hooksを使用すると、機能コンポーネントに状態を持たせ、ライフサイクルメソッドを使用できるため、Classコンポーネントの使用を回避し、よりモジュール化された読みやすいコードを使用できます。

完成したプロジェクトはCodeSandboxチェックアウトできます。

前提条件

このチュートリアルを完了するには、次のものが必要です。

ステップ1—Reactアプリを起動する

まず、新しいアプリを作成する必要があります。 ターミナルウィンドウで、新しいアプリケーションを配置する場所に移動し、次のように入力します。

  1. npx create-react-app react-to-do

注: React 16.8より前は、Reactフックを利用するにはReact16.7のアルファビルドをインストールする必要がありました。 この記事の執筆時点で、 Create React App は、フックをサポートする最新の安定バージョンのReact(16.13.1)をインストールします。

次に、新しいプロジェクトディレクトリに移動します。

  1. cd react-to-do

次に、プロジェクトを実行します。

  1. npm start

ブラウザでlocalhost:3000に移動して、回転するReactロゴを確認します。

これでアプリケーションがセットアップされ、アプリの残りの部分の作成を続行できます。

ステップ2—アプリケーションのスタイリング

スタイリングはこのチュートリアルの焦点ではありませんが、やることタスクを表示するのに役立ちます。

コードエディタでApp.cssを開きます。

  1. nano src/App.css

このファイルの内容を、アプリ全体で使用する3つのクラスに置き換えます。

src / App.css
.app {
  background: #209cee;
  height: 100vh;
  padding: 30px;
}

.todo-list {
  background: #e8e8e8;
  border-radius: 4px;
  max-width: 400px;
  padding: 5px;
}

.todo {
  align-items: center;
  background: #fff;
  border-radius: 3px;
  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.15);
  display: flex;
  font-size: 12px;
  justify-content: space-between;
  margin-bottom: 6px;
  padding: 3px 10px;
}

これにより、apptodo-list、およびtodoのCSSクラスが作成されます。 vh(ビューポートの高さ)単位とflexboxプロパティ(align-itemsおよびjustify-content)を利用します。

スタイリングが完了しました。 これで、CRUDの側面を実装できます。

ステップ3—やること項目を読む

CRUDのReadの部分から始めましょう。 リストを読んで表示できるように、リストを作成する必要があります。

クラスを使用するToDoアプリケーションは、次のようになります。

class App extends Component {
  state = {
    todos: [
      { text: "Learn about React" },
      { text: "Meet friend for lunch" },
      { text: "Build really cool todo app" }
    ]
  }

  setTodos = todos => this.setState({ todos });

  render() {
    return <div></div>
  }
}

React Hooksを使用するため、クラスを使用した場合とは状態が少し異なります。

App.jsを開きます:

  1. nano src/App.js

このファイルを変更して、次の行コードをAppコンポーネントに追加します。

src / App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  const [todos, setTodos] = React.useState([
    { text: "Learn about React" },
    { text: "Meet friend for lunch" },
    { text: "Build really cool todo app" }
  ]);

  return (
    // ...
  );
}

export default App;

コンポーネントは機能コンポーネントです。 以前のバージョンのReactでは、機能コンポーネントは状態を処理できませんでしたが、現在はフックを使用することで処理できます。

  • 最初のパラメーターtodosは、状態に名前を付けるものです。
  • 2番目のパラメーターsetTodosは、状態を設定するために使用するものです。

useStateのフックは、Reactがコンポーネントの状態またはライフサイクルにフックするために使用するものです。 次に、オブジェクトの配列を作成し、状態の始まりを取得します。

メインのAppコンポーネントのreturnで後で使用できるコンポーネントを作成する必要があります。 これをTodoと呼び、todoを渡して、ToDoのtext部分(todo.text)を表示します。

App.jsに再度アクセスし、Appコンポーネントの前に新しいTodoコンポーネントを追加します。

src / App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';

function Todo({ todo }) {
  return (
    <div className="todo">
      {todo.text}
    </div>
  );
};

function App() {
  // ...
}

export default App;

アイテムのリストを作成しましょう。

App.jsに再度アクセスし、returnの内容を次の新しいコード行に置き換えます。

src / App.js
function App() {
  // ...

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
          />
        ))}
      </div>
    </div>
  );
}

JavaScriptメソッドmap()を使用すると、todoアイテムを状態からマッピングし、インデックスで表示することで、アイテムの新しい配列を作成できます。

これにより、app<div>todo-list<div>、およびtodosのマップがTodoに追加されます。コンポーネント。

この時点で、logo.svgは使用されなくなるため、削除することもできます。

src/App.jsファイル全体は、これまでのところ次のようになります。

src / App.js
import React from "react";
import "./App.css";

function Todo({ todo }) {
  return (
    <div className="todo">
      {todo.text}
    </div>
  );
};

function App() {
  const [todos, setTodos] = React.useState([
    { text: "Learn about React" },
    { text: "Meet friend for lunch" },
    { text: "Build really cool todo app" }
  ]);

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
          />
        ))}
      </div>
    </div>
  );
}

export default App;

Webブラウザでアプリケーションを開きます。 3つのやること項目が表示されます。

To-do app view of items

これでデータを読み取っており、CRUDの他の側面に進むことができます。

ステップ4—ToDoアイテムの作成

それでは、ToDoアプリ用の新しいアイテムを作成する権限をアプリケーションに与えましょう。

App.jsファイルにある間に、いくつか追加する必要があります。

まず、TodoFormという別のコンポーネントを追加します。 このコンポーネントでは、次のことを行います。

  • 入力フィールドの空の状態から開始します。
  • 状態を設定することでフォームを更新できます。
  • 送信を処理します。

状態を設定するには、次のように記述します。

const [value, setValue] = React.useState("");

1つ目は「値」で、2つ目は状態の設定方法です。 状態は空から始まり、状態に物事を追加すると、やること項目のリストに追加されます。

addTodo関数を処理できるhandleSubmit変数を追加して、アイテムをリストに追加することをお勧めします。 入力ボックスに何も入力されておらず、ユーザーがENTERを押した場合は、空のアイテムをリストに追加しないようにします。

入力ボックスのあるフォームに機能を追加します。

src / App.js
// ...

function TodoForm({ addTodo }) {
  const [value, setValue] = React.useState("");

  const handleSubmit = e => {
    e.preventDefault();
    if (!value) return;
    addTodo(value);
    setValue("");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        className="input"
        value={value}
        onChange={e => setValue(e.target.value)}
      />
    </form>
  );
}

function App() {
  // ...
}

// ...

この新しいTodoFormコンポーネントをAppコンポーネントに追加します。

src / App.js
function App() {
  // ...

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
          />
        ))}
        <TodoForm addTodo={addTodo} />
      </div>
    </div>
  );
}

addTodo関数を作成してみましょう。

App.js内にとどまり、Appコンポーネントの状態で、関数は既存のアイテムのリストを取得し、新しいアイテムを追加して、その新しいリストを表示できます。

src / App.js
function App() {
  // ...

  const addTodo = text => {
    const newTodos = [...todos, { text }];
    setTodos(newTodos);
  };

  return(
    // ...
  );
}

this.stateがないことに注意してください。 新しいReactフックでは、this.stateは使用できなくなります。これは、新しいフックが特定の場所で暗示されることを理解しているためです。

コードにもスプレッド演算子があります。 todosの前の3つのドットはリストをコピーして、新しいToDoアイテムを追加できるようにします。 次に、前に設定したキーワードを使用して、setTodosで状態を設定します。

Webブラウザでアプリケーションを開きます。 3つのやること項目が表示されているはずです。 新しいやること項目を追加するためのフィールドもあるはずです。

Create function in the to-do app

これでデータを作成し、CRUDの他の側面に進むことができます。

ステップ5—ToDoアイテムの更新

完了したら、やることリストの項目を消す機能を追加しましょう。

Appコンポーネントの状態を変更するには、「完了」ステータスを少し追加する必要があります。 オブジェクトのリストに別のキーと値のペアを追加します。

isCompleted: falseの値を追加することにより、最初にfalseに設定し、プロンプトが表示されたら、trueに変更します。

App.jsに再度アクセスし、isCompletedを状態に追加します。

src / App.js
function App() {
  const [todos, setTodos] = React.useState([
    {
      text: "Learn about React",
      isCompleted: false
    },
    {
      text: "Meet friend for lunch",
      isCompleted: false
    },
    {
      text: "Build really cool todo app",
      isCompleted: false
    }
  ]);

  // ...
}

addTodo関数のような関数が必要になりますが、これはアイテムを「完了」としてマークすることができます。 addTodoで行ったのと同様のことを行います。たとえば、スプレッド演算子を使用して現在のアイテムのリストを取得します。 この関数では、isCompletedステータスをtrueに変更して、完了したことを認識します。 次に、状態を更新し、状態をnewTodosに設定します。

次のコードを更新します。

src / App.js
function App() {
  // ...

  const completeTodo = index => {
    const newTodos = [...todos];
    newTodos[index].isCompleted = true;
    setTodos(newTodos);
  };

  return (
    // ...
  )
}

Todo機能でcompleteTodoを使用すると、その機能を利用できます。 Complete ボタンをクリックすると、textDecoration: line-throughスタイルが追加され、アイテムに取り消し線が引かれます。

三項演算子を使用してアイテムを完成させ、リストを更新します。

src / App.js
function Todo({ todo, index, completeTodo }) {
  return (
    <div
      className="todo"
      style={{ textDecoration: todo.isCompleted ? "line-through" : "" }}
    >
      {todo.text}
      <div>
        <button onClick={() => completeTodo(index)}>Complete</button>
      </div>
    </div>
  );
}

Appコンポーネントを返すTodo部分にcompleteTodoを追加します。

src / App.js
function App() {
  // ...

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
            completeTodo={completeTodo}
          />
        ))}
        <TodoForm addTodo={addTodo} />
      </div>
    </div>
  );
}

Webブラウザでアプリケーションを開きます。 3つのやること項目が表示されます。 やること項目を完了としてマークするための完了ボタンもあります。

To-do app with item updated to a completed state

これでデータが更新され、CRUDの最後の側面に進むことができます。

ステップ6—ToDoアイテムの削除

やることリストの項目が削除されたときに削除する機能を追加しましょう。

removeTodo関数を作成して、 X をクリックしてアイテムを削除すると、そのアイテムが削除されるようにします。 その関数は、Appコンポーネントの状態の下にある他の関数によって配置されます。

src / App.js
function App() {
  // ...

  const removeTodo = index => {
    const newTodos = [...todos];
    newTodos.splice(index, 1);
    setTodos(newTodos);
  };

  return (
    // ...
  )
}

このremoveTodo関数では、再びスプレッド演算子を使用しますが、現在のリストを取得すると、アイテムの配列から選択したインデックスをスプライシングします。 それが削除されたら、setTodosnewTodosに設定することにより、新しい状態に戻ります。

Todo関数で、やること項目を削除するためのボタンを追加する必要があります。

src / App.js
function Todo({ todo, index, completeTodo, removeTodo }) {
  return (
    <div
      className="todo"
      style={{ textDecoration: todo.isCompleted ? "line-through" : "" }}
    >
      {todo.text}
      <div>
        <button onClick={() => completeTodo(index)}>Complete</button>
        <button onClick={() => removeTodo(index)}>x</button>
      </div>
    </div>
  );
}

Appコンポーネントを返すTodo部分にremoveTodoを追加します。

src / App.js
function App() {
  // ...

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
            completeTodo={completeTodo}
            removeTodo={removeTodo}
          />
        ))}
        <TodoForm addTodo={addTodo} />
      </div>
    </div>
  );
}

Webブラウザでアプリケーションを開きます。 3つのやること項目が表示されます。 やること項目を削除するためのXボタンもあります。

To-do app with delete button

これでデータが削除され、CRUDの4つの側面すべてが実装されました。

ステップ7—アプリを完成させる

Todoコンポーネント、TodoFormコンポーネント、およびAppコンポーネントをまとめると、App.jsファイルは次のようになります。

src / App.js
import React from "react";
import "./App.css";

function Todo({ todo, index, completeTodo, removeTodo }) {
  return (
    <div
      className="todo"
      style={{ textDecoration: todo.isCompleted ? "line-through" : "" }}
    >
      {todo.text}
      <div>
        <button onClick={() => completeTodo(index)}>Complete</button>
        <button onClick={() => removeTodo(index)}>x</button>
      </div>
    </div>
  );
}

function TodoForm({ addTodo }) {
  const [value, setValue] = React.useState("");

  const handleSubmit = e => {
    e.preventDefault();
    if (!value) return;
    addTodo(value);
    setValue("");
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        className="input"
        value={value}
        onChange={e => setValue(e.target.value)}
      />
    </form>
  );
}

function App() {
  const [todos, setTodos] = React.useState([
    {
      text: "Learn about React",
      isCompleted: false
    },
    {
      text: "Meet friend for lunch",
      isCompleted: false
    },
    {
      text: "Build really cool todo app",
      isCompleted: false
    }
  ]);

  const addTodo = text => {
    const newTodos = [...todos, { text }];
    setTodos(newTodos);
  };

  const completeTodo = index => {
    const newTodos = [...todos];
    newTodos[index].isCompleted = true;
    setTodos(newTodos);
  };

  const removeTodo = index => {
    const newTodos = [...todos];
    newTodos.splice(index, 1);
    setTodos(newTodos);
  };

  return (
    <div className="app">
      <div className="todo-list">
        {todos.map((todo, index) => (
          <Todo
            key={index}
            index={index}
            todo={todo}
            completeTodo={completeTodo}
            removeTodo={removeTodo}
          />
        ))}
        <TodoForm addTodo={addTodo} />
      </div>
    </div>
  );
}

export default App;

これで、CRUDの4つの側面すべてに対応するアプリケーションができました。 To Doアイテムの作成、To Doアイテムの読み取り、To Doアイテムの更新、およびToDoアイテムの削除。

結論

To Doアプリは、Web開発におけるCRUDに関して、優れたリマインダーまたは出発点になる可能性があります。 情報の読み取り、新しい情報の作成、既存の情報の更新、および情報の削除ができることは、どのアプリケーションでも強力です。

このチュートリアルでは、 React Hooksを使用してCRUDTo-Doリストアプリを作成しました。これにより、コードを明確、簡潔、わかりやすくすることができます。

Reactの詳細については、Reactトピックページで演習とプログラミングプロジェクトを確認してください。