The source code for this blog is available on GitHub.

Blog.

Reactを学ぶ2

Cover Image for Reactを学ぶ2

こちらを参考に。 今から始めるReact入門 〜 React の基本

作業時間:5時間 経過時間:8時間

componentについて

以下で最終的な描画を行う

ReactDOM.render(component,id)

変数は{}内で扱える。

importで定義した名前でrender関数内で呼び出す

import Header from './Header'

export default class Layout extends React.Component{
 render(){
  return(
   <div>
    <Header />
   </div>
  )
 }
}

複数あるときは、配列も使用できる

import Header from './Header'
import Footer from './Footer'

export default class Layout extends React.Component{
 render(){
  let components = [<Header />,<Footer />];
  return(
   <div>
    {components}
   </div>
  )
 }
}

stateについて

stateで定義した情報は、setStateで更新できる。

export default class Layout extends React.Component{
  constructor(){
    super();
    this.state = {title:'welcome'};
  }
  render(){
    setTimeout(
      ()=>{this.setState({title:'welcome sugi!'});},
      2000
    )
    return(
      <div>
        <Header />
        <Footer />
      </div>
    )
  }
}

propsについて

propsを使えば、親コンポーネントで定義した変数は子コンポーネントへ受け渡せる。 親では、変数定義と属性に値を渡す。 子では、propsとして受け取る。 孫コンポーネントにわたせる。子コンポーネントで孫に渡す属性名を定義し親の値をpropsで受け取る。 同コンポーネントに同じ属性で異なる値を設定できる。

// js/Layout.js:親コンポーネント
export default class Layout extends React.Component{
 render(){
  const title = "Welcome sugi!";
   return(
     <div>
      <Header title={title} />
      <Header title={"Thank you"} />
     </div>
   )
 }
}
// js/components/Header.js:子コンポーネント
export default class Header extends React.Component {
 render() {
  return(
    <Title title={this.props.title} />
  );
 }
}
// js/components/Header/Title.js孫コンポーネント
export default class Title extends React.Component {
 render(){
  return(
   <h1>{this.props.title}</h1>
  );
 }
}

stateで定義した場合でも、子コンポーネントに同様に渡せる。 子、孫ではpropsとして受け取れる。

export default class Layout extends React.Component{
  constructor(){
    super();
    this.state = {title:'welcome'};
  }
  render(){
    return(
      <div>
        <Header title={this.state.title} />
        <Header title={'Thank you'} />
        <Footer />
      </div>
    )
  }
}

Eventについて

form系の要素の変更を検知して更新する。 changeTitle関数をpropsで子コンポーネントにわたすことで更新を可能にしている。 子コンポーネント側では、handleChange関数でchangeTitle関数を呼び出し、イベントのデータを引数に入れて返している。これで更新している。onChange属性でトリガーの設定を行い、ハンドラーとしてhandleChangeを設定している。 bind(this)は実行する関数のスコープにおける話らしい。これはイマイチ理解しきれていない。。

// js/Layout.js
export default class Layout extends React.Component{
  ...
  changeTitle = (title) =>{
    this.setState({title});
  }
  render(){
    return(
      <div>
        <Header changeTitle={this.changeTitle.bind(this)} title={this.state.title} />
      </div>
    )
  }
}

// js/components/Header.js
export default class Header extends React.Component{
  handleChange(e){
    const title = e.target.value;
    this.props.changeTitle(title);
  }
  render(){
    return (
      <div>
        ...
        <input value={this.props.title} onChange={this.handleChange.bind(this)} />
      </div>
    )
  }
}

@babel/plugin-proposal-class-propertiesを導入すれば、bindを省略できる。

// js/Layout.js
export default class Layout extends React.Component{
  ...
    render(){
    return(
      <div>
        <Header changeTitle={this.changeTitle} title={this.state.title} />
      </div>
    )
  }
}

以下のようにアローファンクションで省略もできるが、関数を都度生成する問題があるため、基本はbindをつけるか、上記の省略するアプローチとなる。

// js/Layout.js
export default class Layout extends React.Component{
  ...
    render(){
    return(
      <div>
        <Header changeTitle={(e) => this.handleClick(e)} title={this.state.title} />
      </div>
    )
  }
}

More Stories