1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[入門]reactでtodoリストを作成する

Posted at

調べても、自分が欲している内容のreactチュートリアルがなかったので、自分で作成した。
よくあるtodoリストを作成する。
欲していたのは、以下の内容なので、それを盛り込んだチュートリアルになっている。
・functional componentの使用
・アロー関数の使用
・styled-componentsの使用
atomic design, redux, ts など取り入れたかったが、モリモリになってしまうので、そこは気が向いたら。

環境構築

[node](https://nodejs.org/ja/)のinstall

yarnのinstall
npm i --global yarn

version確認
yarn --version

create-react-app のinstall
yarn global add create-react-app
reactアプリの作成
create-react-app todoApp
todoApp は作成するディレクトリ名

reactアプリの立ち上げ
yarn start

localhost:3000 で画面が表示される。
スクリーンショット 2021-07-28 22.35.20.png

hello worldだけを表示できるか試しに、src/App.js を編集する

src/App.js
import './App.css';

function App() {
	return <div className="App">hello world</div>;
}

export default App;

画面を見ると、hello worldとだけ表示されているはず。

コードを書き換えることで、src/App.test.js でエラーがでてしまう。
ここでは、テストファイルを扱わないのでファイルごと削除してしまってよい。

アロー関数

src/App.js でコンポーネントの宣言をアロー関数に書き換える。 [アロー関数式(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
src/App.js
import './App.css';

const App = () => {
	return <div className="App">hello world</div>;
};

export default App;

ヘッダー作成

Header コンポーネントを作成する。
src/Header.js
const Header = () => {
	return <h1>todo app</h1>;
};

export default Header;

HeaderコンポーネントをApp.jsで使用する

src/App.js
import './App.css';
import Header from './Header';

const App = () => {
	return (
		<>
			<Header />
			<div className="App">hello world</div>
		</>
	);
};

export default App;

<></> についてはこちら https://ja.reactjs.org/docs/fragments.html

画面を見るとヘッダーが表示されるが、スタイルがかかっていないため左によってしまう。
スクリーンショット 2021-07-28 22.57.48.png

styled-components

cssはstyled-componentsを使用していく。

styled-componentsのinstall
yarn add styled components

styled-componentsを使ってスタイルを定義
styled-componentsについてはこちら

src/Header.js
import styled from 'styled-components';

const Header = () => {
	return <HeaderComponent>todo app</HeaderComponent>;
};

const HeaderComponent = styled.h1`
	text-align: center;
`;

export default Header;

ヘッダーが中央による
スクリーンショット 2021-07-28 23.08.04.png

todoアプリ作成

todoを入力するフォームを作成する。
src/Form.js
import React from 'react';
import styled from 'styled-components';

const Form = () => {
	return (
		<Component>
			<div>title</div>
			<input name="title" type="text" />
			<div>desc</div>
			<textarea name="desc" type="text" />
		</Component>
	);
};

const Component = styled.div`
	text-align: center;
	margin: 30px auto;
	width: 400px;
	font-weight: bold;
`;

export default Form;

titleとdescを入力できるフォームができた。
スクリーンショット 2021-07-28 23.28.38.png

state

次に、フォームに今何が入力されている状態なのかをわかるようにstateを使う。

useStateをimportして、inputとtextareaにvalueとonChangeの設定をする。

useStateについてはこちら

src/Form.js
import React, { useState } from 'react';
import styled from 'styled-components';

const Form = () => {
	const [title, setTitle] = useState('');
	const [desc, setDesc] = useState('');

	return (
		<Component>
			<div>title</div>
			<input
				name="title"
				type="text"
				value={title}
				onChange={(e) => setTitle(e.target.value)}
			/>
			<div>desc</div>
			<textarea
				name="desc"
				type="text"
				value={desc}
				onChange={(e) => setDesc(e.target.value)}
			/>
		</Component>
	);
};

const Component = styled.div`
	text-align: center;
	margin: 30px auto;
	width: 400px;
	font-weight: bold;
`;

export default Form;

試しに、console.log()仕込んでみて、stateに反映されているか確認

src/Form.js
import React, { useState } from 'react';
import styled from 'styled-components';

const Form = () => {
	const [title, setTitle] = useState('');
	const [desc, setDesc] = useState('');
	console.log(title); // あとで消す
	console.log(desc); // あとで消す
	return (
		<Component>
			<div>title</div>
			<input
				name="title"
				type="text"
				value={title}
				onChange={(e) => setTitle(e.target.value)}
			/>
			<div>desc</div>
			<textarea
				name="desc"
				type="text"
				value={desc}
				onChange={(e) => setDesc(e.target.value)}
			/>
		</Component>
	);
};

const Component = styled.div`
	text-align: center;
	margin: 30px auto;
	width: 400px;
	font-weight: bold;
`;

export default Form;

何か入力するたびに、consoleにログがはかれるはず。

onClickで登録処理

次に、todoを登録。登録したtodoを表示する処理

まず、登録ボタンを作成し、onClickにクリックした時の処理を記述した関数を渡す。
処理内容は、
・todoを登録
・formを空にする
の2つだが、まだtodoの登録先を作っていないので、一旦formを空にする処理だけ記述。

src/Form.js
import React, { useState } from 'react';
import styled from 'styled-components';

const Form = () => {
	const [title, setTitle] = useState('');
	const [desc, setDesc] = useState('');

	const handleSubmit = (e) => {
		e.preventDefault();
		// 入力formを空にする
		setTitle('');
		setDesc('');
	};

	return (
		<Component>
			<div>title</div>
			<input
				name="title"
				type="text"
				value={title}
				onChange={(e) => setTitle(e.target.value)}
			/>
			<div>desc</div>
			<textarea
				name="desc"
				type="text"
				value={desc}
				onChange={(e) => setDesc(e.target.value)}
			/>
			<br />
			<button onClick={handleSubmit}>todoを作成</button>
		</Component>
	);
};

const Component = styled.div`
	text-align: center;
	margin: 30px auto;
	width: 400px;
	font-weight: bold;
`;

export default Form;

titleとdescに文字を入力してからtodoを作成を押すと、入力フォームが空になるはず。
スクリーンショット 2021-07-29 0.21.10.png

propsで登録処理の関数を渡す

todoの登録先はstateを使う。 todoリストに登録していくために、登録処理の関数を作成し、propsでFormコンポーネントに渡す。
App.js
import React, { useState } from 'react';
import Header from './Header';
import Form from './Form';

const App = () => {
	// 登録されたtodoリスト
	const [todos, setTodos] = useState([
		{ id: 0, title: `やること`, desc: 'やることの説明' },
	]);
	// todoのユニークid
	const [id, setId] = useState(1);
	// todosに入力されたtodoを登録する処理
	const addTodo = (todo) => {
		setTodos([...todos, { id, title: todo.title, desc: todo.desc }]);
		setId(id + 1);
	};
	return (
		<>
			<Header />
			<Form addTodo={addTodo} />
		</>
	);
};

export default App;

Form.jsでaddTodoを使ってtodoリストに登録させる

src/Form.js
import React, { useState } from 'react';
import styled from 'styled-components';

const Form = (props) => {
	const [title, setTitle] = useState('');
	const [desc, setDesc] = useState('');

	const handleSubmit = (e) => {
		e.preventDefault();
		// todoListに登録する
		props.addTodo({ title, desc });
		// 入力formを空にする
		setTitle('');
		setDesc('');
	};

	return (
		<Component>
			<div>title</div>
			<input
				name="title"
				type="text"
				value={title}
				onChange={(e) => setTitle(e.target.value)}
			/>
			<div>desc</div>
			<textarea
				name="desc"
				type="text"
				value={desc}
				onChange={(e) => setDesc(e.target.value)}
			/>
			<br />
			<button onClick={handleSubmit}>todoを作成</button>
		</Component>
	);
};

const Component = styled.div`
	text-align: center;
	margin: 30px auto;
	width: 400px;
	font-weight: bold;
`;

export default Form;

todoリストをmapを使用して表示

これだけでは、本当に登録されているか分からないので、
登録されたtodoを表示するコンポーネントを作成する。
propsで受け取ったtodoリストを表示する。
mapを使用して、リスト分作成していく。
その際、keyを指定すること。
mapとkeyについてはこちら

TodoList.js
import React from 'react';

const TodoList = (props) => {
	return (
		<ul>
			{props.todos.map((todo) => (
				<li key={todo.id}>
					<span>{todo.title}</span>
					<br />
					<p>{todo.desc}</p>
				</li>
			))}
		</ul>
	);
};

export default TodoList;

App.jsでTodoListコンポーネントにtodosを渡す。

src/App.js
import React, { useState } from 'react';
import Header from './Header';
import Form from './Form';
import TodoList from './TodoList';

const App = () => {
	// 登録されたtodoリスト
	const [todos, setTodos] = useState([
		{ id: 0, title: `やること`, desc: 'やることの説明' },
	]);
	// todoのユニークid
	const [id, setId] = useState(1);
	// todosに入力されたtodoを登録する処理
	const addTodo = (todo) => {
		setTodos([...todos, { id, title: todo.title, desc: todo.desc }]);
		setId(id + 1);
	};

	return (
		<>
			<Header />
			<Form addTodo={addTodo} />
			<TodoList todos={todos} />
		</>
	);
};

export default App;

入力フォームに文字を入れて、ボタンを押すとページ下部にtodoが追加されていく。
スクリーンショット 2021-07-29 0.48.13.png

細かく書くのは一旦ここまで。気が向いたら追記します。
想定していることは、
・todoが完了したことがわかるように、完了ボタン用意。
・CRUDで言うと、todoを更新、削除できるような処理。
・styeld-components使っておきながら、全然スタイル定義していないので、スタイル整えるのも。
・コンポーネントの切り分け。保守性・拡張性無視しているので、atomic desgin を意識した構成にリファクタ。
・tsの取り込み。(todoリストのオブジェクトの型がないのが気持ち悪い)
・reduxの取り込み。(redux使うほどの規模ではないから難しいかも)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?