render props

Problem

借用react官網(wǎng)的例子悦即,當(dāng)我們需要一個(gè)<Mouse>組件的時(shí)候彼宠,我們直接去實(shí)現(xiàn)它浴捆,我們初始的目標(biāo)是為了實(shí)現(xiàn)一個(gè)移動(dòng)鼠標(biāo)同時(shí)可以顯示鼠標(biāo)位置睛驳,通過封裝可以實(shí)現(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>移動(dòng)鼠標(biāo)!</h1>
                <Mouse />
            </div>
            );
        }
    }

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

    // 這里我們實(shí)現(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>   ......
                但是接著我們需要?jiǎng)?chuàng)建一個(gè)單獨(dú)的 <MouseWithSomethingElse>
                每次我們需要使用它時(shí),<MouseWithCat> 是不是真的可以重復(fù)使用.
                */}
                <Cat mouse={this.state} />
            </div>
            );
        }
    }

Solution (render props)

我們可以提供一個(gè)帶有函數(shù) prop<Mouse> 組件贼涩,它能夠動(dòng)態(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>移動(dòng)鼠標(biāo)!</h1>
                // 使用時(shí)就在<Mouse>組件上設(shè)一個(gè)函數(shù)形式的prop,當(dāng)然這個(gè)屬性名字可以隨便取袒哥,只要和前面對(duì)應(yīng)上就OK缩筛,特殊情況,把這個(gè)的名字設(shè)為children的時(shí)候堡称,可以寫成這樣的形式
                <Mouse>
                    {
                        mouse => (<Cat mouse={mouse} />)
                    }
                </Mouse>
                // 上下兩種情況對(duì)于prop是children的情況是等價(jià)的
                <Mouse render={mouse => (<Cat mouse={mouse} />)}/>
            </div>
            );
        }
    }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瞎抛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子却紧,更是在濱河造成了極大的恐慌桐臊,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晓殊,死亡現(xiàn)場離奇詭異断凶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)巫俺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門认烁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事却嗡〔芭妫” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵窗价,是天一觀的道長如庭。 經(jīng)常有香客問我,道長舌镶,這世上最難降的妖魔是什么柱彻? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任豪娜,我火速辦了婚禮餐胀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瘤载。我一直安慰自己否灾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布鸣奔。 她就那樣靜靜地躺著墨技,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挎狸。 梳的紋絲不亂的頭發(fā)上扣汪,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音锨匆,去河邊找鬼崭别。 笑死,一個(gè)胖子當(dāng)著我的面吹牛恐锣,可吹牛的內(nèi)容都是我干的茅主。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼土榴,長吁一口氣:“原來是場噩夢啊……” “哼诀姚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起玷禽,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤赫段,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后矢赁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糯笙,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年坯台,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了炬丸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖稠炬,靈堂內(nèi)的尸體忽然破棺而出焕阿,到底是詐尸還是另有隱情,我是刑警寧澤首启,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布暮屡,位于F島的核電站,受9級(jí)特大地震影響毅桃,放射性物質(zhì)發(fā)生泄漏褒纲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一钥飞、第九天 我趴在偏房一處隱蔽的房頂上張望莺掠。 院中可真熱鬧,春花似錦读宙、人聲如沸彻秆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唇兑。三九已至,卻和暖如春桦锄,著一層夾襖步出監(jiān)牢的瞬間扎附,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工结耀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留留夜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓饼记,卻偏偏與公主長得像香伴,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子具则,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

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