kindle本「ReactでTodoアプリを作ってみよう」のまとめ。
点数
75点
感想
前半はわかりやすかった。
Material-UIを使っている点がよかった。
Cordovaの説明が雑で、あまり参考にならなかったのが残念。
reactアプリ作成手順
npm init -y
npm install create-react-app
npx create-react-app myapp
- src/App.jsを書き換え
cd myapp
npm start
で実行。
import React from "react";
import logo from './logo.svg';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
title: 'React sites'
};
this.onClick = this.onClick.bind(this);
}
onClick(e) {
this.setState({title: 'clicked! textContent=' + e.target.textContent});
}
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo"/>
<h3>{this.state.title}</h3>
<button onClick={this.onClick}>クリック</button>
</header>
<main>
</main>
</div>
)
}
}
export default App;
双方向バインディング
value属性とonChange属性でそれぞれstate変数を取得、変更する。
テキストボックスは、onChange以外のイベント(onKeyUp, onInputなど)の場合は、value属性ではなくdefaultValue属性を使わなければならない。 (onChange以外のイベントでvalue属性を使用すると、consoleにwarningが表示される)
onChange(e) {
this.setState({inputText: e.target.value});
}
onInput(e) {
this.setState({inputText2: e.target.value});
}
// JSX
<input type="text" value={this.state.inputText} onChange={this.onChange}/>
<input type="text" defaultValue={this.state.inputText2} onInput={this.onInput}/>
リスト表示
mapメソッドを使う。
コールバック関数ではJSXを返却する。
{this.state.todos.map((todo) => {
return (
<p key={todo.id}>{todo.text}</p>
)
})}
リストからの削除
Arrayのfilterメソッドを使う。spliceメソッドでも可。
deleteTodo(e) {
let newTodos = this.state.todos.filter((todo) => todo.id !== Number(e.target.dataset.id));
this.setState({todos: newTodos});
}
// JSX
{this.state.todos.map((todo) => {
return (
<p key={todo.id}>{todo.text}<button onClick={this.deleteTodo} data-id={todo.id}>削除</button></p>
)
})}
コンポーネント間でのデータのやり取り
- componentsフォルダを作成
- Childコンポーネント(components/Child.js)を作成
import React from "react";
class Child extends React.Component {
render() {
return (
<p onClick={this.props.removeMessage}>{this.props.message}</p>
)
}
}
export default Child;
- App.jsにChildコンポーネントの記述を追加
import React from "react";
import Child from "./components/Child";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
message: 'メッセージです。',
};
this.removeMessage = this.removeMessage.bind(this);
}
removeMessage() {
this.setState({message: ''});
}
render() {
return (
<div className="App">
<main className="App-header">
<Child message={this.state.message} removeMessage={this.removeMessage}></Child>
</main>
</div>
)
}
}
export default App;
React Router
npm install react-router-dom
※プロジェクトフォルダに移動してからインストール- compnentsフォルダにPageOne.jsとPageTwo.jsを作成
import {Link} from "react-router-dom";
の後に
<Link to="/pagetwo">ページ2へ</Link>
やtoPageOne() {
this.props.history.push('/')
}
<button onClick={this.toPageOne}></button>
を記述することで、React Routerを利用した画面遷移を行うことができる。
import React from "react";
import {Link} from "react-router-dom";
class PageOne extends React.Component {
componentDidMount() {
alert('created');
}
componentWillUnmount() {
alert('destroyed');
}
render() {
return (
<div>
<p>ページ1</p>
<Link to="/pagetwo">ページ2へ</Link>
</div>
)
}
}
export default PageOne;
import React from "react";
class PageTwo extends React.Component {
constructor(props) {
super(props);
this.toPageOne = this.toPageOne.bind(this);
}
toPageOne() {
this.props.history.push('/')
}
render() {
return (
<div>
<p>ページ2です。</p>
<button onClick={this.toPageOne}>ページ1へ</button>
</div>
)
}
}
export default PageTwo;
- App.jsに追記
import { Route } from "react-router-dom";
および<Route path="/" component={PageOne} exact></Route>
<Route path="/pagetwo" component={PageTwo} exact></Route> - index.jsに追記
import { BrowserRouter } from "react-router-dom";
および<BrowserRouter>
<App />
</BrowserRouter>
React Router(Hashモード)
index.jsの<BrowserRouter>を<HashRouter>にする。
import { HashRouter } from "react-router-dom";
および<HashRouter>
<App />
</HashRouter>
ライフサイクルメソッド
componentDidMount() {
alert('created');
}
componentWillUnmount() {
alert('destroyed');
}
コメント