4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Reactのfunction as childとは何か

Posted at

この記事でReactコンポーネントのchildrenにFunctionを渡していて気になったが、childrenとしてFunctionを渡すパターンがあるらしい

コード

  • propsのchildrenを関数呼び出しするのがポイント
    • TypeScriptで単純にthis.props.childrenを関数呼び出しすると型定義でエラーになった
import * as React from "react";
import * as ReactDOM from "react-dom";

class Container extends React.Component<{}, {}> {
    render(){
        const children = this.props.children as Function;
        return <div>
            {children({foo: "bar"})} // propsのchildrenを関数呼び出し
        </div>
    }
}

class App extends React.Component<{}, {}> {
    render(){
        return <Container>
            {({foo}) => <div>Content {foo}</div>}
        </Container>
    }
}

ReactDOM.render(<App/>, document.getElementById("root"));

何に使えるか

  • このパターンがreact-motionreact-measure等で利用されてるのを見ると、レンダリングに関する複雑な処理をコンポーネントに押し込め、かつ、その処理結果に基づいてchildrenを描画したい場合に使えそうだ
  • こちらでは、propsで渡したurlからfetchした結果に基づいて、childrenを描画するコンポーネントの例が示されているので、このような非同期処理等に係るstateの変化をコンポーネントに押し込めるのにも使えそう

例:タイマーコンポーネント

すごく人工的な例…
一定時間置きに時間更新するという処理をコンポーネントに押し込め、具体的な描画はchildrenコンポーネントでやる

import * as React from "react";
import * as ReactDOM from "react-dom";

class Timer extends React.Component<{ interval: number }, {}> {
    private timer = null;
    state = {
        now: new Date()
    };

    onTimer = () => {
        this.setState({ now: new Date() });
        this.timer = setTimeout(this.onTimer, this.props.interval);
    };

    componentWillMount() {
        this.onTimer();
    }

    componentWillUnmount() {
        clearTimeout(this.timer);
    }

    render() {
        const children = this.props.children as Function;
        return children({ ...this.state, ...this.props });
    }
}

class App extends React.Component<{}, {}> {
    render() {
        return <Timer interval={1000}>
            {({ now }) => <div>Timer {now.toLocaleTimeString()}</div>}
        </Timer>
    }
}

ReactDOM.render(<App />, document.getElementById("root"));

参考文献

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?