React.js official doc

Reactの[Docs](https://reactjs.org/docs/getting-started.html)のMain Concepts部分を訳してみました。Versionは16.4.2。

# Main concepts
## [Hello world](https://reactjs.org/docs/hello-world.html)

```react
import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
    <h1>Hello, world!</h1>,
    document.getElementById('root')
);
```

## [Introducing JSX (JSX入門)](https://reactjs.org/docs/introducing-jsx.html)
JSXに式を埋め込む。

```react
import React from 'react';
import ReactDOM from 'react-dom';

function formatName(user) {
    return user.firstName + ' ' + user.lastName;
}

const user = {
    firstName: 'Harper',
    lastName: 'Perez'
};

//// element ////
const element = (
    <h1>
        Hello, {formatName(user)}!
  </h1>
);

ReactDOM.render(
    element,
    document.getElementById('root')
);
```

## [Rendering Elements](https://reactjs.org/docs/rendering-elements.html)
Reactの要素(element)は不変(immutable)である。一度作成したら属性などを変更できない。ここまでの知識では，UIを更新するためには新しい要素を作って```ReactDOM.render()```に渡す必要がある。

```react
import React from 'react';
import ReactDOM from 'react-dom';

function tick() {
    const element = (
        <div>
            <h1>Hello, world!</h1>
            <h2>It is {new Date().toLocaleTimeString()}.</h2>
        </div>
    );
    ReactDOM.render(element, document.getElementById('root'));
}

setInterval(tick, 1000);
```

## [Components and Props](https://reactjs.org/docs/components-and-props.html)
コンポーネントを定義するもっとも簡単な方法は，JavaScriptの関数を書くことである。

```react
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
```

ES6クラスを使ってコンポーネントを定義することもできる。

```react
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
```

### functionを使った場合

```react
import React from 'react';
import ReactDOM from 'react-dom';

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

const element = <Welcome name="Sara" />;
ReactDOM.render(
  element,
  document.getElementById('root')
);
```

### classを使った場合

```react
import React from 'react';
import ReactDOM from 'react-dom';

class Welcome extends React.Component {
    render() {
        return <h1>Hello, {this.props.name}</h1>;
    }
}

//// Passing a property here ////
const element = <Welcome name="Sara" />;
ReactDOM.render(
    element,
    document.getElementById('root')
);
```

上の例では```Welcome```コンポーネントに対して```{name: 'Sara'}```をプロパティとして渡す。

コンポーネントから別のコンポーネントを参照することもできる。次の例では，```Welcome```コンポーネントを複数回描画する```App```コンポーネントを作ることができる。

```react
import React from 'react';
import ReactDOM from 'react-dom';

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  //// App ////
  <App />,
  document.getElementById('root')
);
```
[CodePen](https://reactjs.org/redirect-to-codepen/components-and-props/composing-components)


## [State and Lifecycle (状態とライフサイクル)](https://reactjs.org/docs/state-and-lifecycle.html)

```react
import React from 'react';
import ReactDOM from 'react-dom';

function Clock(props) {
    return (
        <div>
            <h1>Hello, world!</h1>
            <h2>It is {props.date.toLocaleTimeString()}.</h2>
        </div>
    );
}

function tick() {
    ReactDOM.render(
        <Clock date={new Date()} />,
        document.getElementById('root')
    );
}

setInterval(tick, 1000);
```
上の例では，the fact that the Clock sets up a timer and updates the UI every second should be an implementation detail of the Clockという要件を満たしていない。

### FunctionをClassに変換する
```
class Clock extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  );
}

setInterval(tick, 1000);
```

[CodePen](http://codepen.io/gaearon/pen/zKRGpo?editors=0010)

### Classにlocal stateを追加する

```react
import React from 'react';
import ReactDOM from 'react-dom';

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
```


### Adding Lifecycle Methods to a Class
```Clock``` が最初にDOMを描画したら，タイマーをセットする。これをマウントする，という。
```Clock``` によって生成されたDOMが削除されたら，タイマーをクリアする。これをアンマウントする，という

```react
import React from 'react';
import ReactDOM from 'react-dom';

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  //// componentDidMound ////
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  //// componentWillUnmount ////
  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    //// update local state ////
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
```

## [Handling Events](https://reactjs.org/docs/handling-events.html)
- ReactイベントはcamelCaseで書く

```Toggle``` コンポーネントが"ON"/"OFF"を交互に描画する。

```react
import React from 'react';
import ReactDOM from 'react-dom';

class Toggle extends React.Component {
    constructor(props) {
        super(props);
        this.state = { isToggleOn: true };

        // This binding is necessary to make `this` work in the callback
        //// Binding ////
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState(prevState => ({
            isToggleOn: !prevState.isToggleOn
        }));
    }

    render() {
        return (
            <button onClick={this.handleClick}>
                {this.state.isToggleOn ? 'ON' : 'OFF'}
            </button>
        );
    }
}

ReactDOM.render(
    <Toggle />,
    document.getElementById('root')
);
```

JavaScriptでは，デフォルトではクラスメソッドはバインディングされない。```this.handleClick```と```onClick```をバインドするのを忘れると，コールバックが呼ばれたとき，```this```が```undefined```になる。

## [Conditional Rendering](https://reactjs.org/docs/conditional-rendering.html)
```react
import React from 'react';
import ReactDOM from 'react-dom';

function UserGreeting(props) {
    return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
    return <h1>Please sign up.</h1>;
}

function Greeting(props) {
    const isLoggedIn = props.isLoggedIn;

    //// condition ////
    if (isLoggedIn) {
        return <UserGreeting />;
    }
    return <GuestGreeting />;
}

ReactDOM.render(
    <Greeting isLoggedIn={false} />,
    document.getElementById('root')
);
```

### 要素変数
要素(element)に変数を使うことができる。これは条件に応じて一部だけ再描画するのを助ける。

```react
import React from 'react';
import ReactDOM from 'react-dom';

function UserGreeting(props) {
    return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
    return <h1>Please sign up.</h1>;
}

//// Greeting(message) component ////
function Greeting(props) {
    const isLoggedIn = props.isLoggedIn;
    if (isLoggedIn) {
        return <UserGreeting />;
    }
    return <GuestGreeting />;
}

//// Login button component ////
function LoginButton(props) {
    return (
        <button onClick={props.onClick}>
            Login
    </button>
    );
}

//// Logout button component ////
function LogoutButton(props) {
    return (
        <button onClick={props.onClick}>
            Logout
    </button>
    );
}

class LoginControl extends React.Component {
    constructor(props) {
        super(props);
        //// Binding ////
        this.handleLoginClick = this.handleLoginClick.bind(this);
        this.handleLogoutClick = this.handleLogoutClick.bind(this);

        //// state ////
        this.state = { isLoggedIn: false };
    }

    //// Handler sets state ////
    handleLoginClick() {
        this.setState({ isLoggedIn: true });
    }

    handleLogoutClick() {
        this.setState({ isLoggedIn: false });
    }

    render() {
        const isLoggedIn = this.state.isLoggedIn;
        let button;

        if (isLoggedIn) {
            button = <LogoutButton onClick={this.handleLogoutClick} />;
        } else {
            button = <LoginButton onClick={this.handleLoginClick} />
        }

        return (
            <div>
                <Greeting isLoggedIn={isLoggedIn} />
                {button}
            </div>
        );
    }
}

ReactDOM.render(
    <LoginControl />,
    document.getElementById('root')
);
```

### インラインIf-Else
JSXに式を埋め込むことができる。

```react
render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  );
}
```

### コンポーネントの描画を防ぐ
コンポーネントを描画したくない場合は，nullを返す。


```react
function WarningBanner(props) {
  //// Return null if warn is null ////
  if (!props.warn) {
    return null;
  }

  return (
    <div className="warning">
      Warning!
    </div>
  );
}

class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true};
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }

  handleToggleClick() {
    this.setState(prevState => ({
      showWarning: !prevState.showWarning
    }));
  }

  render() {
    return (
      <div>
        //// Warning banner ////
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? 'Hide' : 'Show'}
        </button>
      </div>
    );
  }
}

ReactDOM.render(
  <Page />,
  document.getElementById('root')
);
```


## [Lists and Keys](https://reactjs.org/docs/lists-and-keys.html)

```javascript
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);
```

結果は

```
 [2, 4, 6, 8, 10] 
```

### Basic List Component

```react
import React from 'react';
import ReactDOM from 'react-dom';

function NumberList(props) {
  const numbers = props.numbers;

  //// build listItems ////
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
  return (
    //// return list ////
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
```

### Keys

For example, if you extract a ListItem component, you should keep the key on the <ListItem /> elements in the array rather than on the <li> element in the ListItem itself.

```react
import React from 'react';
import ReactDOM from 'react-dom';

function ListItem(props) {
  // Correct! There is no need to specify the key here:
  //// valueのみを返す ////
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;

  //// list Items ////
  const listItems = numbers.map((number) =>
    // Correct! Key should be specified inside the array.
    <ListItem key={number.toString()} value={number} />

  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);
```

## [Forms](https://reactjs.org/docs/forms.html)

```react
import React from 'react';
import ReactDOM from 'react-dom';

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    //// value ////
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  //// Event handler for text, setting state ////
  handleChange(event) {
    this.setState({value: event.target.value});
  }

  //// Event handler for submit, show alert ////
  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          //// Call event handler every keystoroke ////
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ReactDOM.render(
  <NameForm />,
  document.getElementById('root')
);
```


## [Lifting State Up](https://reactjs.org/docs/lifting-state-up.html)
複数のコンポーネント間で，同様の変更を反映したい場合がある。その場合は，共通の先祖(common ancestor)と状態(state)を共有することを推奨する。

1．与えられた温度で水が沸騰するか計算する
2．まず，摂氏をプロパティとして受け付けるコンポーネントを作る
3．次に，華氏を入力として受け付ける
4．温度を変化する関数を作る(摂氏を華氏に。華氏を摂氏に)
5．それぞれの入力を同期させる必要がある。摂氏を更新したら，華氏も反映される。

Reactでは共通の先祖に状態を持ち上げることで状態の共有を実現する。
これを"Lifting state up"と呼ぶ。
```TemperatureInput```から得られるローカルステートを取り除き，代わりに```Calculator```に移動させる。

```react
import React from 'react';
import ReactDOM from 'react-dom';

const scaleNames = {
  c: 'Celsius',
  f: 'Fahrenheit'
};

//// 華氏to摂氏 ////
function toCelsius(fahrenheit) {
  return (fahrenheit - 32) * 5 / 9;
}

//// 摂氏to華氏 ////
function toFahrenheit(celsius) {
  return (celsius * 9 / 5) + 32;
}

function tryConvert(temperature, convert) {
  const input = parseFloat(temperature);
  if (Number.isNaN(input)) {
    return '';
  }
  const output = convert(input);
  const rounded = Math.round(output * 1000) / 1000;
  return rounded.toString();
}

//// 沸騰する/しない /////
function BoilingVerdict(props) {
  if (props.celsius >= 100) {
    return <p>The water would boil.</p>;
  }
  return <p>The water would not boil.</p>;
}

//// 入力フォーム ////
class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  //// プロパティで渡されたハンドラ
  ////  handleCelsiusChangeまたはhandleFahrenheitChangeを呼ぶ ////
  handleChange(e) {
    this.props.onTemperatureChange(e.target.value);
  }

  render() {
    //// 渡された温度 ////
    const temperature = this.props.temperature;

    //// 渡された単位 ////
    const scale = this.props.scale;

    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature} onChange={this.handleChange} />
      </fieldset>
    );
  }
}

/// 計算クラス
class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
    this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
    this.state = {temperature: '', scale: 'c'};
  }

  //// 上位のイベントハンドラー ////
  handleCelsiusChange(temperature) {
    this.setState({scale: 'c', temperature});
  }

  //// 上位のイベントハンドラー ////
  handleFahrenheitChange(temperature) {
    this.setState({scale: 'f', temperature});
  }

  render() {
    const scale = this.state.scale;
    const temperature = this.state.temperature;
    const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
    const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;

    return (
      <div>
        //// プロパティとしてhandleCelsiusChangeを渡す ////
        <TemperatureInput
          scale="c"
          temperature={celsius}
          onTemperatureChange={this.handleCelsiusChange} />

        //// プロパティとしてhandleFahrenheitChangeを渡す ////
        <TemperatureInput
          scale="f"
          temperature={fahrenheit}
          onTemperatureChange={this.handleFahrenheitChange} />

        <BoilingVerdict
          celsius={parseFloat(celsius)} />
      </div>
    );
  }
}

ReactDOM.render(
  <Calculator />,
  document.getElementById('root')
);
```

## [Composition vs Inheritance (コンポジットと継承)](https://reactjs.org/docs/composition-vs-inheritance.html)
Reactでは継承の代わりにコンポジション(composition)を使うことを推奨する。
Reactを初めて使う開発者は継承を求めるが，それをコンポジションでどのように解決するか示す。

- ```child```プロパティを使って子エレメントを渡す

```react
function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      //// child: Welcome Thank you for.... ////
      {props.children}
    </div>
  );
}

function WelcomeDialog() {
  return (
    <FancyBorder color="yellow">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}

ReactDOM.render(
  <WelcomeDialog />,
  document.getElementById('root')
);
```

## [Thinking in React](https://reactjs.org/docs/thinking-in-react.html)
### Step1: UIをコンポーネント階層に分解する
- FilterableProductTable (全体を包含する)
  - SearchBar (ユーザーの入力を受け付ける)
  - ProductTable (ユーザー有力に基づきデータコレクションを表示する)
      - ProductCategoryRow (各カテゴリーの先頭)
      - ProductRow (各プロダクト)

### Step2: 静的バージョンを作る
インタラクティブでないUIを作ってみる。この段階ではステートを使わないこと。

### Step 3: Identify The Minimal (but complete) Representation Of UI State

何がステートか見ていこう。各データについて次の3つの質問に答えるだけ。
1. 親コンポーネントからプロパティを経由して渡されるか？もしそうであれば，それはステートではない。
2. 時間の経過にともない変化しないか？もしそうであれば，それはステートではない。
3. それは，ほかの状態の変化やプロパティの値から計算できるか？もしそうであれば，それはステートではない。