React入門その③ stateとprops
前回から新たに学んだことの自分用メモです。
前回とほぼ同じ機能の簡単なアプリケーションです。前回のものに比べて、「 この選択肢は既に存在します。 」というメッセージが出る機能を追加したくらいです。
新たに学んだ事
- Reactコンポーネント
- React.Component から派生したコンポーネントを作る
- コンポーネントは入れ子にできる。
- React props(プロパティ)
- 子となるコンポーネントに値や関数を渡す(読み取り専用)
- 関数が実行できるよう親コンポーネントの contructor で bind が必要
- この書き方は見苦しくて苦痛。回避策あり。
- state
- Stateless functional component(関数コンポーネント)
- コンポーネントが状態を持たない場合(例:決まったヘッダーを表示するだけのコンポーネント)は、 React.Componen から派生したクラスのコンポーネントを使わず、const Example =(props) => { return (…); } という形式を用いることができる。
- defaultProps
- props(プロパティ)の初期値を設定する。
- state の初期値として props を指定し、その初期値を defaultProps で指定する方法がある。
コード
class IndecisionApp extends React.Component {
constructor(props) {
super(props);
this.handleDeleteOptions = this.handleDeleteOptions.bind(this);
this.handlePick = this.handlePick.bind(this);
this.handleAddOption = this.handleAddOption.bind(this);
this.state = {
options: props.options
};
}
handleDeleteOptions() ({
this.setState(() => { options: [] }));
}
handlePick() {
const randomNum = Math.floor(Math.random() * this.state.options.length);
const option = this.state.options[randomNum];
alert(option);
}
handleAddOption(option) {
if (!option) {
return "適切な値を入力してください";
} else if (this.state.options.indexOf(option) > -1) {
return "この選択肢は既に存在します。";
}
this.setState(prevState => ({
options: prevState.options.concat(option)
}));
}
render() {
const subtitle = "あなたの人生をコンピュータに委ねる。";
return (
<div>
<Header subtitle={subtitle} />
<Action
hasOptions={this.state.options.length > 0}
handlePick={this.handlePick}
/>
<Options
options={this.state.options}
handleDeleteOptions={this.handleDeleteOptions}
/>
<AddOption handleAddOption={this.handleAddOption} />
</div>
);
}
}
IndecisionApp.defaultProps = {
options: []
};
const Header = (props) => {
return (
<div>
<h1>{props.title}</h1>
{props.subtitle && <h2>{props.subtitle}</h2>}
</div>
);
}
Header.defaultProps = {
title: "優柔不断"
};
const Action = (props) => {
return (
<div>
<button
onClick={props.handlePick}
disabled={!props.hasOptions}
>
私はどうすればいい?
</button>
</div>
);
}
const Options = (props) => {
return (
<div>
<button onClick={props.handleDeleteOptions}>すべて削除</button>
<ol>
{props.options.map(option => (
<Option key={option} optionText={option} />
))}
</ol>
</div>
);
}
const Option = (props) => {
return (
<div>
<li>{props.optionText}</li>
</div>
);
}
class AddOption extends React.Component {
constructor(props) {
super(props);
this.handleAddOption = this.handleAddOption.bind(this);
this.state = {
error: undefined
};
}
handleAddOption(e) {
e.preventDefault();
const option = e.target.elements.option.value.trim();
const error = this.props.handleAddOption(option);
this.setState(() => ({ error }));
}
render() {
return (
<div>
{this.state.error && <p>{this.state.error}</p>}
<form onSubmit={this.handleAddOption}>
<input type="text" name="option" />
<button>選択肢の追加</button>
</form>
</div>
);
}
}
ReactDOM.render(<IndecisionApp />, document.getElementById("app"));






ディスカッション
コメント一覧
まだ、コメントがありません