Reactjs 为什么单击展开按钮会关闭react中的侧面板?

Reactjs 为什么单击展开按钮会关闭react中的侧面板?,reactjs,Reactjs,我有一个侧面板,上面列出了一些项目。当列表项内容溢出时,显示展开按钮,单击展开btn将显示列表项的全部内容 为此,我创建了一个可扩展组件。当列表项内容溢出时,这将显示向下箭头,单击向下箭头将显示向上箭头 但是,在下面的代码中,单击按钮1只会使sidpanel消失,而不是出现箭头。谁能帮我解决这个问题。谢谢 export default class Expandable extends React.PureComponent{ constructor(props) { su

我有一个侧面板,上面列出了一些项目。当列表项内容溢出时,显示展开按钮,单击展开btn将显示列表项的全部内容

为此,我创建了一个可扩展组件。当列表项内容溢出时,这将显示向下箭头,单击向下箭头将显示向上箭头

但是,在下面的代码中,单击按钮1只会使sidpanel消失,而不是出现箭头。谁能帮我解决这个问题。谢谢

export default class Expandable extends React.PureComponent{
    constructor(props) {
        super(props);
        this.expandable_ref = React.createRef();
        this.state = {
           expanded: false,
           overflow: false,
        };
     }

    componentDidMount () {
        if (this.expandable_ref.current.offsetHeight < 
             this.expandable_ref.current.scrollHeight) {
             this.setState({overflow: true});
        }
    }

    on_expand = () => {
        this.setState({expanded: true});
        console.log("in expnad");
    };

    on_collapse = () => {
        this.setState({expanded: false});
    };

    render () {

        return (
            <div className={(this.state.overflow ? 
            this.props.container_classname : '')}>
                <div className={(this.state.overflow ? 
                this.props.classname : '')} style={{overflow: 'hidden', 
                display: 'flex', height: (this.state.expanded ? null : 
                this.props.base_height)}}
                ref={this.expandable_ref}>
                    {this.props.children}
                </div>
                {this.state.overflow && this.state.expanded &&
                    <div className={this.props.expand}>
                        <button  onClick={this.on_collapse}> 
                            {this.props.arrow_up}</button>
                    </div>}
                {this.state.overflow && !this.state.expanded &&
                    <div className={this.props.expand}>
                        <button onClick={this.on_expand}> 
                            {this.props.arrow_down}</button>
                    </div>}

            </div>
        );
    }
}
导出默认类Expandable Expands React.PureComponent{
建造师(道具){
超级(道具);
this.expandable_ref=React.createRef();
此.state={
扩展:错,
溢出:错误,
};
}
组件安装(){
如果(这是可扩展的)参考当前的离视
此.expandable\u ref.current.scrollHeight){
this.setState({overflow:true});
}
}
on_expand=()=>{
this.setState({expanded:true});
console.log(“在expnad中”);
};
on_collapse=()=>{
this.setState({expanded:false});
};
渲染(){
返回(
{this.props.children}
{this.state.overflow&&this.state.expanded&&
{this.props.arrow_up}
}
{this.state.overflow&!this.state.expanded&&
{this.props.arrow_down}
}
);
}
}
在上面的代码中,我将基准高度传递为42px

编辑:

我已经意识到,对于侧面板组件,如果用户单击侧面板之外的任何位置,我会添加eventlistener单击以关闭侧面板。当我删除eventlistener时,它可以正常工作

class sidepanel extends React.PureComponent {
    constructor(props) {
        super(props);
        this.sidepanel_ref = React.createRef();
    }

    handle_click = (event) => {
        if (this.sidepanel_ref.current.contains(event.target)) {
            return;
        } else {
            this.props.on_close();
        }
    };

    componentDidMount() {
        document.addEventListener('click', this.handle_click, false);
    }

    componentWillUnmount() {
        document.removeEventListener('click', this.handle_click, false);
    }

    render() {
        return (
            <div>
                <div className="sidepanel" ref= 
                    {this.sidepanel_ref}>
                    {this.props.children}
                </div>
            </div>
        );
    }
}
类侧面板扩展了React.PureComponent{
建造师(道具){
超级(道具);
this.sidepanel_ref=React.createRef();
}
句柄\单击=(事件)=>{
if(此侧面板参考当前包含(事件目标)){
返回;
}否则{
这个.props.on_close();
}
};
componentDidMount(){
document.addEventListener('click',this.handle\u click,false);
}
组件将卸载(){
document.removeEventListener('click',this.handle\u click,false);
}
render(){
返回(
{this.props.children}
);
}
}
当我记录event.target和sidepanel_ref.current时,我在这两个文件中都看到了按钮元素,但svg在这两个文件中似乎有所不同


我如何解决这个问题?

可能是因为单击事件会像在DOM中一样在组件树中弹出气泡。如果一个元素中有一个
onClick
处理程序,而另一个元素中有另一个
onClick
处理程序,则会同时触发这两个处理程序。在内部元素的处理程序中使用
event.stopPropagation()
,以阻止事件冒泡:

export default class Expandable extends React.PureComponent{
    constructor(props) {
        super(props);
        this.expandable_ref = React.createRef();
        this.state = {
           expanded: false,
           overflow: false,
        };
     }

    componentDidMount () {
        if (this.expandable_ref.current.offsetHeight < 
             this.expandable_ref.current.scrollHeight) {
             this.setState({overflow: true});
        }
    }

    toggleCollapse = event => {
        // use preventDefault here to stop the event from bubbling up
        event.stopPropagation();
        this.setState(({expanded}) => ({expanded: !expanded}));
    };

    render () {
        const {className, container_classname, base_height, expand, arrow_up, arrow_down} = this.props;
        const {overflow, expanded} = this.state;

        return (
            <div className={overflow ? container_classname : ''}>
                <div 
                    className={overflow ? classname : ''} 
                    style={{
                        overflow: 'hidden', 
                        display: 'flex', 
                        height: expanded ? null : base_height
                    }}
                    ref={this.expandable_ref}
                >
                    {this.props.children}
                </div>
                {overflow && (
                    <div className={expand}>
                        <button onClick={this.toggleCollapse}> 
                            {expanded ? arrow_up : arrow_down}
                        </button>
                    </div>
                )}
            </div>
        );
    }
}
导出默认类Expandable Expands React.PureComponent{
建造师(道具){
超级(道具);
this.expandable_ref=React.createRef();
此.state={
扩展:错,
溢出:错误,
};
}
组件安装(){
如果(这是可扩展的)参考当前的离视
此.expandable\u ref.current.scrollHeight){
this.setState({overflow:true});
}
}
toggleCollapse=事件=>{
//在此处使用preventDefault可阻止事件冒泡
event.stopPropagation();
this.setState(({expanded})=>({expanded:!expanded}));
};
渲染(){
const{className,container\u className,base\u height,expand,arrow\u up,arrow\u down}=this.props;
const{overflow,expanded}=this.state;
返回(
{this.props.children}
{溢出&&(
{扩展?向上箭头:向下箭头}
)}
);
}
}

可能是因为单击事件在组件树中冒泡,就像它们在DOM中一样。如果一个元素中有一个
onClick
处理程序,而另一个元素中有另一个
onClick
处理程序,则会同时触发这两个处理程序。在内部元素的处理程序中使用
event.stopPropagation()
,以阻止事件冒泡:

export default class Expandable extends React.PureComponent{
    constructor(props) {
        super(props);
        this.expandable_ref = React.createRef();
        this.state = {
           expanded: false,
           overflow: false,
        };
     }

    componentDidMount () {
        if (this.expandable_ref.current.offsetHeight < 
             this.expandable_ref.current.scrollHeight) {
             this.setState({overflow: true});
        }
    }

    toggleCollapse = event => {
        // use preventDefault here to stop the event from bubbling up
        event.stopPropagation();
        this.setState(({expanded}) => ({expanded: !expanded}));
    };

    render () {
        const {className, container_classname, base_height, expand, arrow_up, arrow_down} = this.props;
        const {overflow, expanded} = this.state;

        return (
            <div className={overflow ? container_classname : ''}>
                <div 
                    className={overflow ? classname : ''} 
                    style={{
                        overflow: 'hidden', 
                        display: 'flex', 
                        height: expanded ? null : base_height
                    }}
                    ref={this.expandable_ref}
                >
                    {this.props.children}
                </div>
                {overflow && (
                    <div className={expand}>
                        <button onClick={this.toggleCollapse}> 
                            {expanded ? arrow_up : arrow_down}
                        </button>
                    </div>
                )}
            </div>
        );
    }
}
导出默认类Expandable Expands React.PureComponent{
建造师(道具){
超级(道具);
this.expandable_ref=React.createRef();
此.state={
扩展:错,
溢出:错误,
};
}
组件安装(){
如果(这是可扩展的)参考当前的离视
此.expandable\u ref.current.scrollHeight){
this.setState({overflow:true});
}
}
toggleCollapse=事件=>{
//在此处使用preventDefault可阻止事件冒泡
event.stopPropagation();
this.setState(({expanded})=>({expanded:!expanded}));
};
渲染(){
const{className,container\u className,base\u height,expand,arrow\u up,arrow\u down}=this.props;
const{overflow,expanded}=this.state;
返回(
{this.props.children}
{溢出&&(
{扩展?向上箭头:向下箭头}
)}
);
}
}
侧盘怎么样