Reactの特徴
-
Compositional
-
Declarative code
- いちいちいちいち処理の詳細まで書かない
- (e.g.)
const longNames = people.filter(name => name.length > 6)
- (c.f.) Imperative code ではない
-
Unidirectional Dataflowを使う
- dataflowはparent elementからchildrenの一方向に伝搬される
- 子は親の持つデータを参照できる。子は親のデータを変更しようと思ったらその旨を親に伝え、親がそれをデータの変更を行う
- Data-Binding ではない
- Data-Bindingを使うと、appのどこからでも保持していたデータを変更できる
Reactでelementを作る
-
React.createElement( <tag name>, <propsのhash(=オブジェクト)>, <content in tag> );
で、仮想DOMを初期化。- e.g.
const element = React.createElement('div', null, 'My name is Tyler, and I love porcupines.');
- creteElementしただけでは、描画されない。これを、
ReactDOM.render(element), document.getElementById('root')
とかして、DOMに反映する。 - propsにはhashを渡す。有効なキーは
className
とかhtmlFor
とか。- DOM要素では、ある要素のclassにアクセスするには、
cName = elementNodeReference.className;
とするから。
- DOM要素では、ある要素のclassにアクセスするには、
- e.g.
Reactでネストしたelementを作る方法
import React from 'react'
import ReactDOM from 'react-dom'
const people = [
{ name: "John", id: 0 },
{ name: "Paul", id: 1 }
]
const element = React.createElement('ol', null,
people.map((person) => (
// 子要素を配列にする時は、propsがそれぞれの要素でユニークなkeyを持っていないと怒られる
React.createElement('li', {key: people.id}, person.name)
))
)
ReactDOM.render(
element,
document.getElementById('root')
)
- JSX(=syntax extention for JS)という拡張構文を使うことで、上記のコードもHTMLチックに、楽に書ける。
// 上記のcreateElementの箇所をJSXで書き換えると、
const element = <ol>
{people.map((person) => (
<li key={person.id}>{person.name}</li>
))}
</ol>
Class ComponentとStateless Functional Component
作ったReact componentクラスをexportする方法
export default ListContacts
初期化時にstateをプロパティーとしてComponentに持たせる方法
class User extends React.Component {
constructor(props) {
super(props);
this.state = {
username: 'Tyler'
};
}
}
Babelでトランスコンパイルするなら以下でもいける。
class User extends React.Component {
state = {
username: 'Tyler'
}
}
- Avoid initializing that state with props! (e.g.
this.state = {user: props.user}
)
stateの更新
-
this.state.hoge = new_hoge
という風に更新しても、re-renderingされない。 - 引数の関数の返り値が元のstateにマージされる。
this.setState((prevState) => (
{count: prevState.count + 1}
)
- なお、元のstateの値を使う必要がないなら、引数にハッシュを渡せばいい。
this.setState({ count: 2 })
stateの型チェック
-
yarn add prop-types
でprop-typesというパッケージをインストールして以下のように使う。
ListContacts.propTypes = {
contacts: PropTypes.array.isRequired,
onDeleteContact: PropTypes.func.isRequired,
}
- Componentを定義したクラス内で定義するには、
static propTypes = {
contacts: PropTypes.array.isRequired,
onDeleteContact: PropTypes.func.isRequired,
}
form component
- フォームに打ち込んだ値をそのままフォームのvalueにするのではなく、一旦stateに収納して、それをsource of truthとして使う。
const { query } = this.state // state.queryをqueryに取り出して、
updateQuery(query) {
this.setState(() => ({
query: query.trim() // valueがqueryというstateに収納される
}))
}
render() {(
<input
className='search-contacts'
type='text'
placeholder='Search Contacts!'
value={query}
onChange={(event) => this.updateQuery(event.target.value)} // evnt.target.valueで入力値が取れる
/>
)}
- 以下にちょっとハマった。
<form onSubmit={(event) => { ////// onSubmit()はeventを引数にとる関数を渡す
event.preventDefault(); ////// 書かなかいと、画面がrefreshされてstateが初期値に戻った...
this.props.addItem(this.state.value)
}}>
</form>
yarnコマンド
yarn start
Starts the development server.
yarn build
Bundles the app into static files for production.
yarn test
Starts the test runner.
yarn eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can’t go back!