render props

Problem

借用react官網(wǎng)的例子,當(dāng)我們需要一個<Mouse>組件的時候,我們直接去實現(xiàn)它,我們初始的目標(biāo)是為了實現(xiàn)一個移動鼠標(biāo)同時可以顯示鼠標(biāo)位置,通過封裝可以實現(xiàn),如下:

    class Mouse extends React.Component {
        constructor(props) {
            super(props);
            this.handleMouseMove = this.handleMouseMove.bind(this);
            this.state = { x: 0, y: 0 };
        }

        handleMouseMove(event) {
            this.setState({
                x: event.clientX,
                y: event.clientY
            });
        }

        render() {
            return (
            <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>

                {/* ...但我們?nèi)绾武秩?<p> 以外的東西? */}
                <p>The current mouse position is ({this.state.x}, {this.state.y})</p>
            </div>
            );
        }
    }

    class MouseTracker extends React.Component {
        render() {
            return (
            <div>
                <h1>移動鼠標(biāo)!</h1>
                <Mouse />
            </div>
            );
        }
    }

但是實現(xiàn)了上面的<MouseTracker>組件后,需求又變了,我們需要實現(xiàn)的不只是顯示鼠標(biāo)位置了,同時需要在該位置上顯示一個<Cat>組件,這意味著我們需要再次卻封裝一個新的組件<MouseWithCat>,在這個組件里面包含了<Cat position={x: this.state.x, y: this.state.y} />,其目的就是為了<Cat>組件可以使用<Mouse>組件內(nèi)部的狀態(tài),但是這就需要我們必須去再次封裝一個新的組件,如果最后需要的有各式各樣的要求,針對每一個要求都去實現(xiàn)一個新的組件,而且這些組件都充斥著大量重復(fù)的代碼,這樣的工作是無意義的,且會帶來代碼的冗長。

    // 這里我們實現(xiàn)了<MouseWithCat>,那如果我們還需要<MouseWithDog>呢?是不是還要再把這一套代碼再寫一遍?這明顯是重復(fù)的工作
    class MouseWithCat extends React.Component {
        constructor(props) {
            super(props);
            this.handleMouseMove = this.handleMouseMove.bind(this);
            this.state = { x: 0, y: 0 };
        }

        handleMouseMove(event) {
            this.setState({
            x: event.clientX,
            y: event.clientY
            });
        }

        render() {
            return (
            <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>

                {/*
                我們可以在這里換掉 <p> 的 <Cat>   ......
                但是接著我們需要創(chuàng)建一個單獨的 <MouseWithSomethingElse>
                每次我們需要使用它時,<MouseWithCat> 是不是真的可以重復(fù)使用.
                */}
                <Cat mouse={this.state} />
            </div>
            );
        }
    }

Solution (render props)

我們可以提供一個帶有函數(shù) prop<Mouse> 組件,它能夠動態(tài)決定什么需要渲染的,而不是將 <Cat> 或是 <Dog> 硬編碼到 <Mouse> 組件里,并有效地改變它的渲染結(jié)果,這樣就避免了大量重復(fù)的代碼

    // 首先修改<Mouse>組件的代碼,在最后render的內(nèi)容區(qū)域留一塊用來render將要傳進(jìn)來的內(nèi)容
    class Cat extends React.Component {
        render() {
            const mouse = this.props.mouse;
            return (
            <img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
            );
        }
        }

        class Mouse extends React.Component {
        constructor(props) {
            super(props);
            this.handleMouseMove = this.handleMouseMove.bind(this);
            this.state = { x: 0, y: 0 };
        }

        handleMouseMove(event) {
            this.setState({
            x: event.clientX,
            y: event.clientY
            });
        }

        render() {
            return (
            <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>

                {/*
                Instead of providing a static representation of what <Mouse> renders,
                use the `render` prop to dynamically determine what to render.
                */}
                {this.props.render(this.state)}
            </div>
            );
        }
        }

        class MouseTracker extends React.Component {
        render() {
            return (
            <div>
                <h1>移動鼠標(biāo)!</h1>
                // 使用時就在<Mouse>組件上設(shè)一個函數(shù)形式的prop,當(dāng)然這個屬性名字可以隨便取,只要和前面對應(yīng)上就OK,特殊情況,把這個的名字設(shè)為children的時候,可以寫成這樣的形式
                <Mouse>
                    {
                        mouse => (<Cat mouse={mouse} />)
                    }
                </Mouse>
                // 上下兩種情況對于prop是children的情況是等價的
                <Mouse render={mouse => (<Cat mouse={mouse} />)}/>
            </div>
            );
        }
    }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • React的設(shè)計模式有很多種,比如無狀態(tài)組件/表現(xiàn)型組件,有狀態(tài)組件/容器型組件,render模式組件,高階組件等...
    Perkin_閱讀 7,038評論 1 9
  • "Render Props"是指一種在 React 組件之間使用一個值為函數(shù)的 prop 共享代碼的簡單技術(shù)。具有...
    Kevin丶CK閱讀 424評論 0 1
  • 在軟件開發(fā)的過程中Code Reuse和可讀性一直是開發(fā)人員致力于解決的問題,在React社區(qū)中,以往出現(xiàn)了很多的...
    aaronisme閱讀 791評論 0 1
  • 首先打個廣告,系列文章: 古老的React mixins HOC(高階組件) render props React...
    DC_er閱讀 1,345評論 0 0
  • 人活著為了什么 工作,生活 為了生活努力工作 活著才可能有精神 忙碌可帶來充實的自己 才可有進(jìn)取的心能動力 人活著...
    月牙兒彎閱讀 449評論 0 1

友情鏈接更多精彩內(nèi)容