无法从父级为子级设置道具

时间:2016-05-16 02:55:54

标签: reactjs

我正在尝试使用lightbox的src。该代码似乎不适用于最新版本的react。无法在LightboxTrigger组件中为父组件设置子项的道具。

使用反应0.12的工作示例。 example

var LightboxModal = React.createClass({

    whiteContentStyles: {
        position: 'fixed',
        top: '25%',
        left: '30%',
        right: '30%',
        backgroundColor: '#fff',
        color: '#7F7F7F',
        padding: '20px',
        border: '2px solid #ccc',
        borderRadius: '20px',
        boxShadow: '0 1px 5px #333',
        zIndex:'101'
    },

    blackOverlayStyles: {
        background: 'black',
        opacity: '.5',
        position: 'fixed',
        top: '0px',
        bottom: '0px',
        left: '0px',
        right: '0px',
        zIndex: '100'
    },

    closeTagStyles: {
        float: 'right',
        marginTop: '-30px',
        marginRight: '-30px',
        cursor: 'pointer',
        color: '#fff',
        border: '1px solid #AEAEAE',
        borderRadius: '30px',
        background: '#605F61',
        fontSize: '31px',
        fontWeight: 'bold',
        display: 'inline-block',
        lineHeight: '0px',
        padding: '11px 3px',
        textDecoration: 'none'
    },

    componentDidMount: function(){
        document.addEventListener("keydown", function (e) {
            if ( (this.props.display) && (e.keyCode === 27) ){
                this.props.closeLightbox();
            }
        }.bind(this));
    },

    render: function(){
        for (var j in this.props){
            if (j !== 'children'){
                this.props.children.props[j] = this.props[j];
            }
        }

        if (this.props.display){
            return (
                <div>
                    <div style={this.blackOverlayStyles} onClick={this.props.closeLightbox} />
                    <div style={this.whiteContentStyles}>
                        <a style={this.closeTagStyles} onClick={this.props.closeLightbox}>&times;</a>
                        {this.props.children}
                    </div>
                </div>
            );
        } else {
            return (<div></div>);
        }
    }
});


var LightboxTrigger = React.createClass({
    render: function(){

        this.props.children.props.onClick = this.props.openLightbox;
        for (var j in this.props){
            if (j !== 'children'){
                this.props.children.props[j] = this.props[j];
            }
        }
        return this.props.children;
    }
});


var Lightbox = React.createClass({

    getInitialState: function(){
        return { display: false };
    },

    componentWillMount: function(){
        if (this.props.data)
            this.setState(this.props.data);
    },

    openLightbox: function(){
        this.setState({display: true});
    },

    closeLightbox: function(){
        this.setState({display: false});
    },

    setLightboxState: function(obj){
        this.setState(obj);
    },

    render: function(){
        var childrenWithProps = React.Children.map(this.props.children, function(child) {
            var childProps = {
                openLightbox: this.openLightbox,
                closeLightbox: this.closeLightbox,
                setLightboxState: this.setLightboxState
            };
            console.log(childProps)
            for (var j in this.state){
                childProps[j] = this.state[j];
            }

            var childWithProps = React.cloneElement(child, childProps);

            return childWithProps;
        }, this);

        return (
            <div>
                {childrenWithProps}
            </div>
        );
    }
});

我在dom中呈现这个。

<Lightbox>
    <LightboxTrigger>
        <a href="#">Click to open</a>
    </LightboxTrigger>
    <LightboxModal>
        <div>
           <h1>This is the basic usage!</h1>
           <p>Good luck :D</p>
        </div>
    </LightboxModal>
 </Lightbox>

1 个答案:

答案 0 :(得分:1)

如果您使用的是React 14或更高版本,则props对象现在已冻结,无法进行变异。您可以使用React.cloneElement代替。

您可以阅读此更改here和React.CloneElement here