このページの目標
- [ ] 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; //受け取り側 } }