React.js

初心者向けのReact.jsで作る超簡単なtodoアプリ

初心者向けのReact.jsで作る超簡単なtodoアプリ

みなさんこんにちは、からんです。

今回はReact.js製の簡単なtodoアプリの作り方の解説をします。

仕様

リストを追加していくだけの簡単な内容になっていてリストを削除する機能はありません。

最初が下記です。

やることを追加すると下記になりやる事が増えていきます。

デモ

デモはここから見ることができます。

最初のコード

簡単にやりたいのでnpm インストールはせずバベルでやります。

下記のコードをHTMLファイルに貼り付けて下さい。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Reactで作ったToDoリスト</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.8.2/css/bulma.min.css" />
  <link href="./css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
  <div id="root"></div>

  <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.2.6/index.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <script type="text/babel">

  const TodoApp = () => {
    
    //ここに記述していく
    
    
    
    
  };

  
const root = document.getElementById('root');
ReactDOM.render(<TodoApp />, root);

  </script>
</body>
</html>

20行目と31行目に「TodoApp」がありますが名前が同じでないとエラーになるので必ず同じ名前にしてください。

それでは解説スタートです。

まずはやることを入力するボックスと登録ボタンを作ります。

やることを入力するボックスと登録ボタンの作成

コードを下記にします。

const TodoApp = () => {

  //ここから追加
    return(
      <div class="wrap">
        <h2>ToDoリスト</h2>
        <div class="form">
          <input 
            type="text" 
            value={value} 
            placeholder="やることを入力"
          />
          <button>追加する</button>
        </div>
      </div>
    );
  //ここまで追加
};

10行目のvalue属性が{value}になっているのは後で使うからです。

inputタグに入力した値を受け取ることができる(変更できる)ようにするのでuseStateを使います。

入力した内容を受け取ることができるようにする

コードを下記にします。

const TodoApp = () => {
    const [value,setValue] = React.useState('');  <!--この行を追加-->

    //ここから追加
    const ListAdd = e => {
      const newValue = e.target.value;
      setValue(newValue);
    };
    //ここまで追加

    return(
      <div class="wrap">
        <h2>ToDoリスト</h2>
        <div class="form">
          <input 
            type="text" 
            value={value} 
            placeholder="やることを入力"
            onChange={ListAdd}               //この行を追加
          />
          <button>追加する</button>
          </ul>
        </div>
      </div>
    );
  };

2行目のvalueが16行目のvalueに対応しています。

本当に値を受け取っているかを確認するために入力した値を表示する方法があります。

「<button>追加する</button>」の下に<p>{value}</p>として下さい。

inputタグに文字を書き込むと下に表示されます、下記みたいな感じです。

確認ができたら<p>{value}</p>を消してください。

次は「追加する」ボタンを押すとやることが表示されるようにします。

やることを追加できるようにする

コードを下記にします。

const TodoApp = () => {
    const [value,setValue] = React.useState('');
    const [todoList,setTodoList] = React.useState([]);       //この行を追加

    const ListAdd = e => {
      const newValue = e.target.value;
      setValue(newValue);
    };

    //ここから追加
    const Add = () => {
      const newTodo = [...todoList,value];
      setTodoList(newTodo);
    };
    //ここまで追加

    return(
      <div className="wrap">
        <h2>ToDoリスト</h2>
        <div className="form">
          <input 
            type="text" 
            value={value} 
            placeholder="やることを入力"
            onChange={ListAdd}
          />
          <button onClick={Add}>追加する</button>           //この行を修正する
        </div>
      </div>
    );
  };

3行目のuseStateですがやることを追加できるようにするために初期値を[ ](配列)にしています。

12行目の…todoListはスプレッド演算子ですが配列に値を追加していくので使いました。

それではやることを表示します。

やることの表示

コードを下記にします。

const TodoApp = () => {
    const [value,setValue] = React.useState('');
    const [todoList,setTodoList] = React.useState([]);

    const ListAdd = e => {
      const newValue = e.target.value;
      setValue(newValue);
    };

    const Add = () => {
      const newTodo = [...todoList,value];
      setTodoList(newTodo);
    };

    return(
      <div className="wrap">
        <h2>ToDoリスト</h2>
        <div className="form">
          <input 
            type="text" 
            value={value} 
            placeholder="やることを入力"
            onChange={ListAdd}
          />
          <button onClick={Add}>追加する</button>
          
          //ここから追加
          <ul>
            {
              todoList.map((todo,i) => (
                <li key={i}>{todo}</li>
              ))
            }
          </ul>
          //ここまで追加
          
        </div>
      </div>
    );
};

表示する内容をmapメソッドを使って埋め込みます。

29行目に(todo,i)がありますがReactではliタグに表示する時に表示した内容に対して番号を付けないといけません。

例えば「りんご→みかん→バナナ→もも」の順にリストを追加するなら「1:りんご→2:みかん→3:バナナ→4:もも」のように番号をつけないといけないということです。

そのために29行目に(todo,i)の「i」と30行目に「key={i}」があります。(2つのiは対応しているので必ず同じにしてください)

これでほとんど完成ですがこのままだと「やることを入力」と書いてある所にやることを入力して「追加する」を押すとやることは追加されますがフォームに入力した内容は残っています。

「やることを入力」の所は消えないと不自然なので消します。

「やることを入力」を消す

コードを下記にします。

const TodoApp = () => {
    const [value,setValue] = React.useState('');
    const [todoList,setTodoList] = React.useState([]);

    const ListAdd = e => {
      const newValue = e.target.value;
      setValue(newValue);
    };

    const Add = () => {
      const newTodo = [...todoList,value];
      setTodoList(newTodo);

      setValue('');       //この行を追加
    };

    return(
      <div className="wrap">
        <h2>ToDoリスト</h2>
        <div className="form">
          <input 
            type="text" 
            value={value} 
            placeholder="やることを入力"
            onChange={ListAdd}
          />
          <button onClick={Add}>追加する</button>
          <ul>
            {
              todoList.map((todo,i) => (
                <li key={i}>{todo}</li>
              ))
            }
          </ul>
        </div>
      </div>
    );
  };

setValue関数の中身を「”」にするだけです。

これで完成です。

完成形のコードを載せます。

完成系のコード


<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Reactで作ったToDoリスト</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.8.2/css/bulma.min.css" />
  <link href="./css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
  <div id="root"></div>

  <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.2.6/index.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <script type="text/babel">

  const TodoApp = () => {
    const [value,setValue] = React.useState('');
    const [todoList,setTodoList] = React.useState([]);

    const ListAdd = e => {
      const newValue = e.target.value;
      setValue(newValue);
    };

    const Add = () => {
      const newTodo = [...todoList,value];
      setTodoList(newTodo);
      setValue('');
    };

    return(
      <div className="wrap">
        <h2>ToDoリスト</h2>
        <div className="form">
          <input 
            type="text" 
            value={value} 
            placeholder="やることを入力"
            onChange={ListAdd}
          />
          <button onClick={Add}>追加する</button>
          <ul>
            {
              todoList.map((todo,i) => (
                <li key={i}>{todo}</li>
              ))
            }
          </ul>
        </div>
      </div>
    );
  };

  
const root = document.getElementById('root');
ReactDOM.render(<TodoApp />, root);

  </script>
</body>
</html>