2017-09-23 161 views
2

我想添加一個新的屬性到頂級組件中的嵌套子元素。通過嵌套的兒童組件映射在反應

我更高級別的組件被稱爲Photo.js

import React, {Component} from 'react'; 
import PropTypes from 'prop-types'; 

export default class Photo extends Component{ 

    constructor(props){ 
    super(props); 
    this.onHandleLoad = this.onHandleLoad.bind(this); 

    this.state = { 
     isLoaded:false 
    } 
    } 

    onHandleLoad(event){ 
    this.setState({ 
     isLoaded:true 
    }) 
    } 

    render(){ 
    const {children} = this.props; 
    return(
     <div className="photo-container"> 
     {children} 
     </div> 
    ) 
    } 
} 

這裏是我加的孩子吧。

<Photo > 
     <Link to='/bla' className="slide-show-link"> 
     <img src={photo.photo} alt={`${photo.title} photo`}/> 
     </Link> 
    </Photo> 

它並不總是相同的孩子添加。有時它可能會更多地嵌套,但它總是有一個元素。 我想要一種能夠映射所有嵌套元素並找到img元素並添加自定義道具的方法。

我想添加的道具是onLoad = {this.onHandleLoad),所以它會調用Photo中的onHandleLoad和正確的範圍。

我看了React.Children.map,但只返回第一個元素而不是嵌套元素。 img可能會降低1級或更多。 我該怎麼做。正在研究遞歸映射,但並不確定這是怎麼回事。有沒有內置的方法來處理這個?

回答

2

做到這一點的最好方法可能是使用像redux這樣的東西,併爲每個圖片加載分派一個動作。但是如果你目前沒有使用它,那將需要大量的重構。

還有另一種方式很適合這裏是context。有many warnings about using context,但由於您只提供回調,所以沒有太大的風險。

上下文將允許您的父組件在回調中傳遞任意數量的級別,而無需通過每個級別的道具。

-

首先添加childContextTypesgetChildContext到父組件:

export default class Photo extends Component { 
    static childContextTypes = { 
    onHandleLoad: PropTypes.func 
    }; 

    constructor(props) { 
    super(props); 

    this.state = { 
     isLoaded: false 
    } 
    } 

    getChildContext() { 
    return { 
     onHandleLoad: this.onHandleLoad 
    }; 
    } 

    onHandleLoad = (event) => { 
    this.setState({ 
     isLoaded: true 
    }) 
    } 

    render() { 
    const {children} = this.props; 
    return(
     <div className="photo-container"> 
     {children} 
     </div> 
    ) 
    } 
} 

然後你需要在你的<img>個孩子部件的包裝掛接到父上下文使用contextTypes

class PhotoImage extends Component { 
    static contextTypes = { 
    onHandleLoad: PropTypes.func 
    } 

    static propTypes = { 
    photo: PropTypes.string, 
    title: PropTypes.string 
    } 

    render() { 
    return (
     <img 
     src={photo} 
     alt={`${title} photo`} 
     onLoad={this.context.onHandleLoad} 
     /> 
    ) 
    } 
} 
+0

哦,這是非常感謝。希望他們不會在接下來的幾個版本中刪除上下文。我遠離它,但你是對的最簡單的方法。 –