简体   繁体   中英

Can't pass extra props to this.props.children

The following React component handles the enter and exit animations of my site's notifications, which it receives through 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 );

It generally works fine, but I would like to pass the hideNotification prop to this.props.children so that, besides being hidden automatically after three seconds, the notification can also be hidden at the click of a 'close' button which is included in the children components.

I've read about React.cloneElement() and tried replacing my this.props.children with the following:

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

but when I test it, as soon as the notification is mounted to the DOM React throws this error:

Invalid value for prop handlehidenotification on tag. Either remove it from the element, or pass a string or number value to keep it in the DOM

I can't understand what the problem is...

As props.chidren is like a list of components, you must iterate over it:

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

I think the best way to solve your problem is to include a close button with a onClick event which fires a method which will call props.hideNotification . You will have to add the button just before you inject 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> ); } } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM