next.js React状态不会更新

taor4pac  于 2023-05-17  发布在  React
关注(0)|答案(1)|浏览(133)

我知道已经有很多关于这个主题的问题被问到了,但是真的感觉每个问题都是不同的,我找不到一个与我的问题足够接近的问题。
我有一个可拖动ItemComponent s的网格。选择后,将显示其他操作图标(ItemActionIcon)。我非常想取消选择组件(并有效地隐藏动作图标),一旦其中一个动作被点击。

所以在第77行<div onClick={() => this.setState({selected: false})} key={index}>中,我尝试将selected的状态更新为false。它已经在文件中提到的所有其他情况下工作得很好。但这次不是。当我单击图标时,我可以通过调试器(或者在我尝试时使用console.log)看到onClick操作按预期触发,ItemComponent甚至得到了对render方法的另一个调用,但this.state.selected仍然设置为true

import React, {Component} from "react";
import Draggable, {DraggableBounds} from "react-draggable";
import ItemComponentAction from "./ItemComponentAction";
import ItemActionIcon from "./ItemActionIcon";

export interface Position {
    x: number;
    y: number;
}

export interface ItemComponentProps {
    gridSquareSize: number;
    canvasBounds: DraggableBounds;
    margin: number;
    position: Position;
}

interface ItemComponentState {
    gridSquareSize: number;
    canvasBounds: DraggableBounds;
    margin: number;
    selected: boolean;
}

export default abstract class ItemComponent extends Component<ItemComponentProps> {

    protected abstract readonly icon: string;
    protected abstract readonly actions: ItemComponentAction[];

    state: ItemComponentState;

    protected constructor(props: ItemComponentProps) {
        super(props);
        this.state = {
            gridSquareSize: props.gridSquareSize,
            canvasBounds: props.canvasBounds,
            margin: props.margin,
            selected: false
        };
    }

    render() {
        return (
            <Draggable grid={[this.state.gridSquareSize / 2, this.state.gridSquareSize / 2]}
                       defaultPosition={{
                           x: this.state.margin + this.props.position.x * this.state.gridSquareSize,
                           y: this.state.margin + this.props.position.y * this.state.gridSquareSize
                       }}
                       handle=".handle"
                       bounds={this.state.canvasBounds}
                       onDrag={() => this.setState({selected: false})}
            >
                <div tabIndex={0}
                     className="handle"
                     onClick={() => this.setState({selected: true})}
                     onBlur={() => this.setState({selected: false})}
                     style={{
                        position: 'absolute',
                        backgroundColor: 'red',
                        width: this.state.gridSquareSize,
                        height: this.state.gridSquareSize,
                        cursor: "move"
                     }}
                >
                    {this.icon}

                    {
                        !this.state.selected || !this.actions.length
                           ? null
                           : (
                                <div style={{
                                    position: 'absolute',
                                    bottom: "0"
                                }}>
                                    {
                                        this.actions.map((action, index) => (
                                            <div onClick={() => this.setState({selected: false})} key={index}>
                                                <ItemActionIcon {...action}/>
                                            </div>
                                        ))
                                    }
                                </div>
                            )
                    }
                </div>
            </Draggable>
        );
    }
}

那你是怎么回事

cuxqih21

cuxqih211#

组件的外部<div>有自己的onClick处理程序,该处理程序将状态值设置回false。尝试在内部onClick处理的事件上使用stopPropagation()。这将阻止事件传播到外部父<div>,并且只有内部onClick处理程序在单击时才会执行。

{
  !this.state.selected || !this.actions.length ? null : (
    <div
      style={{
        position: "absolute",
        bottom: "0"
      }}
    >
      {this.actions.map((action, index) => (
        <div
          onClick={e => {
            e.stopPropagation();
            this.setState({ selected: false });
          }}
          key={index}
        >
          <ItemActionIcon {...action} />
        </div>
      ))}
    </div>
  );
}

相关问题