在内部事件上反应组件更改道具

时间:2018-09-05 19:13:35

标签: javascript reactjs

我正在创建一个react组件,该组件需要根据道具显示隐藏dom元素。在下面,您将找到问题的基本概念。该代码简化了。

<UploadManager
    show={show}
>
{content}
</UploadManager>

组件

export default class UploadManager extends React.Component{

    openDrawer(){
        // change props.open ???
    }

    render(){
        <Drawer
          visible={this.props.show}
        >
         <p>Content</p>
        </Drawer>
        <Button onClick={this.openDrawer} />
    }
}

说明

    组件show
  1. UploadManager道具打开/关闭Drawer component
  2. 父组件可以传递show道具并显示/隐藏抽屉。我让这部分正常工作。
  3. 需要帮助:该组件具有一个浮动按钮。单击时,应打开(显示)抽屉。表示应将this.props.show设置为true

我试图维护用于管理抽屉的显示/隐藏属性的组件的内部状态,但是由于道具+状态的介入,它变得过于虫草。

4 个答案:

答案 0 :(得分:1)

您的答案很好,只是您不需要openDrawer组件中的UploadManager,实际上它可以是虚拟功能组件,这是一个可行的解决方案:

const UploadManager = ({show, onClick}) => (
   <Drawer visible={show}>
     <p>Content</p>
   </Drawer>
   <Button onClick={onClick} />
);

父级组件应为

onClickShowButton = () => {
   this.setState({show: true});
}

render(){
   return (
     <UploadManager 
          show={this.state.show} 
          onClick={this.onClickShowButton}
     >
       {content}
     </UploadManager>
   );
}

答案 1 :(得分:0)

需要从父级传递回调以更改道具。下面是解决此问题的方法。

this.onClickShowButton()是父级的方法。

父组件

onClickShowButton = () => {
    this.setState({show: true});
}

render(){
    return <UploadManager
        show={this.state.show}
        onClickShowButton={this.onClickShowButton}
    >
    {content}
    </UploadManager>
}

在组件上

检查回调是否是一个函数,然后执行它。做得完美吗!

export default class UploadManager extends React.Component{

    openDrawer = () => {
        if (typeof(this.props.onClickShowButton) === 'function') {
            this.props['onClickShowButton']();
        }
    }

    render(){
        <Drawer
          visible={this.props.show}
        >
         <p>Content</p>
        </Drawer>
        <Button onClick={this.openDrawer} />
    }
}

如果是,它将执行它。我不知道这种方法的正确性。如果有人有更好的答案,我会接受的。

答案 2 :(得分:0)

执行以下操作:

组件:

export default class UploadManager extends React.Component {

    constructor(props){
        super(props);
        this.state = {
            openDrawer : props.show
        }
    }
    componentDidUpdate(){
        this.setState({
            openDrawer: this.props.show
        })
    }
    openDrawer = () =>{
        this.setState({
            openDrawer : !this.state.openDrawer
        })
    }
    render() {
        <div>
            <Drawer
                visible={this.state.openDrawer}
            >
                <p>Content</p>
            </Drawer>
            <Button onClick={this.openDrawer} />
        </div>
    }
}

答案 3 :(得分:0)

如果父组件只是将上传管理器的初始状态设置为在首次渲染时显示或隐藏抽屉,则可以执行以下操作:

    <UploadManager
        show={show}
    >
    {content}
    </UploadManager>

    export default class UploadManager extends React.Component{
        constructor(props){
           super(props);
           this.state = {
              open: props.show
           }
        }
        openDrawer(){
            this.setState({open: true});
        }

        render(){
            <Drawer
              visible={this.state.open}
            >
             <p>Content</p>
            </Drawer>
            <Button onClick={this.openDrawer} />
        }
    }

通过这种方式,组件的初始状态将是其父级传递的show属性,然后单击按钮时,此状态将更新,并且基于组件状态显示抽屉。但是,如果您想控制父级传递的show属性,并希望通过它控制抽屉,则应该执行以下操作:

    <UploadManager
        show={show}
        onUpdateShowState={()=>{this.setState({show: true})}}
    >
    {content}
    </UploadManager>

    export default class UploadManager extends React.Component{

        openDrawer(){
            this.props.onUpdateShowState()
        }

        render(){
            <Drawer
              visible={this.props.show}
            >
             <p>Content</p>
            </Drawer>
            <Button onClick={this.openDrawer} />
        }
    }

在上述代码中,您正在使用传递到组件的show属性控制抽屉,并通过调用另一个使用以下属性更新父状态的属性来对其进行更新:this.setState({show:true})- >因此,这里指的是您的父组件,其中已经定义了show,应该将其写在uploadManager的父组件内