无法将额外的道具传递给this.props.children

时间:2018-06-18 08:26:43

标签: javascript reactjs

以下React组件处理我的网站通知的输入和退出动画,它通过this.props.children收到:

class NotificationWrapper extends React.Component {

    constructor( props ) {              
        super( props );                 
        this.state = { timer: setTimeout( this.props.hideNotification, 3000 ) }     
    }

    static getDerivedStateFromProps( props, state ) {
        if( props.notification.override ) {             
            clearTimeout( state.timer );            
            return {
                timer: setTimeout( props.hideNotification, 3000 )            
            }       
        }       
        return null; 
    }

    handleCloseNotification() {         
        this.props.hideNotification();      
    }

    render() {      
        return(
            <CSSTransition 
                appear
                classNames="v-slide"            
                in={ this.props.in } 
                mountOnEnter
                timeout={ 200 }
                unmountOnExit
                onEntered={ () => { this.state.timer } }
            >
                { this.props.children }             
            </CSSTransition>
        );  
    }

}

function mapStateToProps( { notification } ) {  return { notification } }

export default connect( mapStateToProps, { hideNotification } )( NotificationWrapper );

它通常可以正常工作,但我想将hideNotification道具传递给this.props.children,这样除了在三秒钟后自动隐藏,通知也可以在点击''时隐藏关闭'按钮,包含在子组件中。

我已阅读React.cloneElement()并尝试使用以下内容替换this.props.children

{
    React.cloneElement( this.props.children, {
        handleHideNotification: this.props.hideNotification
    })
}

但是当我测试它时,只要将通知挂载到DOM React就会抛出此错误:

  

标记上的道具handlehidenotification的值无效。或   从元素中删除它,或传递一个字符串或数字值来保持   它在DOM中

我无法理解问题是什么......

2 个答案:

答案 0 :(得分:0)

由于props.chidren就像一个组件列表,你必须迭代它:

{React.Children.map(this.props.children, child => {
  return React.cloneElement(child, { handleHideNotification: 'your prop here' });
 })}

答案 1 :(得分:0)

我认为解决问题的最佳方法是包含一个带有onClick事件的关闭按钮,该按钮会触发一个调用props.hideNotification的方法。您必须在注入props.children之前添加按钮。

import React, { Fragment } from 'React';

class NotificationWrapper extends React.Component {

    constructor( props ) {              
        super( props );                 
        this.state = { timer: setTimeout( this.props.hideNotification, 3000 ) }     
    }

    static getDerivedStateFromProps( props, state ) {
        if( props.notification.override ) {             
            clearTimeout( state.timer );            
            return {
                timer: setTimeout( props.hideNotification, 3000 )            
            }       
        }       
        return null; 
    }
    

    handleCloseNotification() {         
        this.props.hideNotification();      
    }

    render() {      
        return(
            <CSSTransition 
                appear
                classNames="v-slide"            
                in={ this.props.in } 
                mountOnEnter
                timeout={ 200 }
                unmountOnExit
                onEntered={ () => { this.state.timer } }
            >
                <Fragment>
                  <button onClick="handleCloseNotification">Close</button>
                  { this.props.children }
                </Fragment>
                           
            </CSSTransition>
        );  
    }

}