ReactNativeアプリの作り方::Props&State

このページの目標

  • [ ] Reactコンポーネントの状態管理の仕組みを理解する
  • [ ] PropsとStateの特性を理解する
  • [ ] 画面を越えた状態の受け渡し方を理解する(ReactNavigation)

Props

PropsはReactコンポーネントに渡す引数を指します

渡す側

class App extends React.Component{
  render(){
    //JSXリテラルで指定されるものがProps(name&iconUrl)
    <Person  name={name} iconUrl={icon.url} />
    {Person(name:name, iconUrl:icon.url)} //上と等価の表現
  }
}

受け取り側

Propsはconstrucorの引数かそれ以外の関数ではthis.propsで参照できます。
自分自身のPropsを更新することは出来ませんが、親コンポーネントが新しいPropsを再度受け渡すことがあります。その場合componentDidUpdateが呼ばれます。componentDidUpdateは初期化時には呼ばれないので注意が必要です。

interface Props {
 name: string;
 iconUrl: string;
}

class Person extends React.Component<Props> {
  constructor(props: Props){
    super(props);
    const name = props.name;
  }
  componentDidUpdate(prevProps: Props){
     if(this.props.name !== prevProps.name) { 
        // do something.
     }
  }
}

State

Stateは名前の通りコンポーネントの状態を管理するオブジェクトです。コンポーネントはStateの変更を検知すると再描画する仕組みになっています。

interface Props {
  id: number;
}
interface State {
 isLoading: boolean;
 name?: string;
 iconUrl?: string;
}

class Person extends React.Component<Props> {
  constructor(props: Props){
    super(props);
    this.state = { isLoading: true }; //初期化はコンストラクタで直接代入する
  }
  async componentDidMount() {
     const response = await fetch(`https:exmaple.com/users/${this.props.id}`);
     const {name, iconUrl} = await response.json();
     this.setState({name, iconUrl, isLoading: false}); //状態の更新はthis.setState経由で行う
  }
  render() {
    if(this.state.isLoading) { // Stateを参照する場合は直接アクセス出来る
      return <LoadingView>
    } else {
      const {name, iconUrl} = this.state;
      return <ProfileRow name={name} iconUrl={iconUrl} />
    }
  }
}

Navigation.State

画面間で値を受け渡したい時はNavigation.Stateの仕組みを利用します。これはReactNavigationの提供する機能です。 navigation.navigate する際にparamプロパティを渡すと遷移先のコンポーネントではprops.navigation.state.paramsからアクセスが可能です。

const params = {userName: this.state.userName}
this.props.navigation.navigate({ routeName: HomeScreen.routeName, params }); // 受け渡し側
type Navigation = NavigationScreenProp<NavigationRoute<any>, any>; //Props型が複雑なためaliasを作成
interface Props {
  navigation: Navigation; 
}

class HomeScreen extends React.Component<Props> {
  constructor(props: Props) {
    super(props);
    const userName = props.navigation.state.params.userName; //受け取り側
  }
}