renderProps使用

介紹和使用render propsjavascript

什麼是render prop

官方解釋:render prop是一種在React組件之間使用一個值爲函數的prop共享代碼的技術 即便用了render這個prop的組件,接受一個函數來渲染元素,即父組件控制這部分的顯示內容,而不是組件內部去實現本身的渲染邏輯。而父組件渲染的元素使用的數據是子組件內部控制的狀態。 好比下面這個例子:java

<SearchList render={ data => ({
        data.map(item => <li key={item.id}>{item.name}</li>)
    })}/>
複製代碼

data即爲SearchList組件內部的state。async

爲何要使用render prop

試想下面這種場景: 實現一個組件,用戶邊輸入,邊搜索,搜索結果展現爲一個列表 實現思路:函數

  1. 首先須要一個輸入框和一個結果列表
  2. 使用debounce,間隔一段時間請求一次,渲染結果
export default class SearchList extends React.Component {
    constructor(props) {
        super(props);
        this.lastFetchId = 0;
        this.handleSearch = debounce(this.handleSearchB, 600);
        this.state = {
            value: '',
            optionList: [], // 可選列表
        };
    }
    onChange = (e) => {
        const value = e && e.target && e.target.value;
        this.handleSearch(value);
    }
    handleSearch = async (val) => {
        if (val) {
            this.lastFetchId += 1;
            const fetchId = this.lastFetchId;
             if (fetchId !== this.lastFetchId) {
                    return;
            }
            // 此處請求並處理結果
        }
    }
    render() {
        const { value, optionList } = this.state;
        return (
            <div className='content'> <input type="text" value={value} onChange={this.onChange} placeholder="請輸入"/> <ul className="search-list"> { optionList.map(item => ( <li className="item" key={item.id}>{item.name}</li> } </ul> </div> ); } } 複製代碼

上面實現了基本的功能,請求防抖和列表展現; 下面改動一下需求:fetch

若是一個頁面須要顯示的是商品列表,另外一個頁面顯示的品牌列表,展現的形式是同樣的,可是由於接口的不一樣,須要展現的內容可能不同。好比品牌列表須要展現品牌名,品牌知名度,商品列表須要展現商品名稱,商品屬性等信息;對於品牌,若是返回結果爲空,則展現用戶輸入的品牌,並添加此品牌保證他始終能搜到結果。this

你可能會想到把列表放到父組件去維護,渲染的時候採用children的方式,這是一種方法,由於父組件自己也須要使用列表數據,可是列表的處理邏輯更多的在子組件中,我的以爲這種處理方式並無達到組件封裝的目的。spa

這樣就能夠用到render prop來解決了code

商品列表:xml

<SearchList render={ data => ({
        data.map(item => <li key={item.id}>{item.goodsName}({item.speciations})</li>)
    })}/>
複製代碼

品牌列表:接口

<SearchList render={ (data, value) => ({
        (data.length === 0 && val ? [{
            id: '',
            brandName: val,
        }] : data).map(item => <li key={item.id}>{item.brandName}</li>)
    })}/>
複製代碼

修改一下SearchList組件

render () {
    <ul className="search-list">
        {this.props.render(optionList)}
    </ul>
}
複製代碼

總結

總結:render prop是一個用於告知組件須要渲染什麼內容的函數prop,而具體的使用場景就是一個組件渲染的部分,須要父組件決定,雖然大多數場景咱們能夠經過使用children prop的方式來實現,但當父組件須要渲染的部分的數據依賴子組件內部狀態時,就須要使用render prop了,更直白的說,就是這個組件的基礎功能是提供可變數據源的時候,具體展現能夠從外部注入。

可變數據源組件:本身不知道要渲染什麼,只是一個基礎數據提供者

相關文章
相關標籤/搜索