調べても、自分が欲している内容のreactチュートリアルがなかったので、自分で作成した。
よくあるtodoリストを作成する。
欲していたのは、以下の内容なので、それを盛り込んだチュートリアルになっている。
・functional componentの使用
・アロー関数の使用
・styled-componentsの使用
atomic design, redux, ts など取り入れたかったが、モリモリになってしまうので、そこは気が向いたら。
環境構築
[node](https://nodejs.org/ja/)のinstallyarnの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
hello worldだけを表示できるか試しに、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)import './App.css';
const App = () => {
return <div className="App">hello world</div>;
};
export default App;
ヘッダー作成
Header コンポーネントを作成する。const Header = () => {
return <h1>todo app</h1>;
};
export default Header;
Headerコンポーネントを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
画面を見るとヘッダーが表示されるが、スタイルがかかっていないため左によってしまう。

styled-components
cssはstyled-componentsを使用していく。styled-componentsのinstall
yarn add styled components
styled-componentsを使ってスタイルを定義
styled-componentsについてはこちら
import styled from 'styled-components';
const Header = () => {
return <HeaderComponent>todo app</HeaderComponent>;
};
const HeaderComponent = styled.h1`
text-align: center;
`;
export default Header;
todoアプリ作成
todoを入力するフォームを作成する。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;
state
次に、フォームに今何が入力されている状態なのかをわかるようにstateを使う。
useStateをimportして、inputとtextareaにvalueとonChangeの設定をする。
useStateについてはこちら
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に反映されているか確認
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を空にする処理だけ記述。
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を作成を押すと、入力フォームが空になるはず。

propsで登録処理の関数を渡す
todoの登録先はstateを使う。 todoリストに登録していくために、登録処理の関数を作成し、propsでFormコンポーネントに渡す。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リストに登録させる
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についてはこちら
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を渡す。
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が追加されていく。

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


