我正在尝试使用React
钩子将类重构为无状态组件。
组件本身非常简单,我看不出我在哪里犯了错误,因为它几乎是从react文档中复制粘贴的。
当用户点击按钮时,组件会显示一个弹出窗口(按钮通过道具传递到我的组件(。我正在使用typescript
。
我在hooks
版本中评论了未能执行我想要的操作的行
这是我原来的课程:
export interface NodeMenuProps extends PropsNodeButton {
title?: string
content?: JSX.Element
button?: JSX.Element
}
export interface NodeMenuState {
visible: boolean
}
export class NodeMenu extends React.Component<NodeMenuProps, NodeMenuState> {
state = {
visible: false
}
hide = () => {
this.setState({
visible: false
})
}
handleVisibleChange = (visible: boolean) => {
this.setState({ visible })
}
render() {
return (
<div className={this.props.className}>
<div className={styles.requestNodeMenuIcon}>
<Popover
content={this.props.content}
title={this.props.title}
trigger="click"
placement="bottom"
visible={this.state.visible}
onVisibleChange={this.handleVisibleChange}
>
{this.props.button}
</Popover>
</div>
</div>
)
}
}
这是React hooks
版本:
export interface NodeMenuProps extends PropsNodeButton {
title?: string
content?: JSX.Element
button?: JSX.Element
}
export const NodeMenu: React.SFC<NodeMenuProps> = props => {
const [isVisible, setIsVisible] = useState(false)
const hide = () => {
setIsVisible(false)
}
const handleVisibleChange = (visible: boolean) => {
console.log(visible) // visible is `true` when user clicks. It works
setIsVisible(visible) // This does not set isVisible to `true`.
console.log(isVisible) // is always `false` despite `visible` being true.
}
return (
<div className={props.className}>
<div className={styles.requestNodeMenuIcon}>
<Popover
content={props.content}
title={props.title}
trigger="click"
placement="bottom"
visible={isVisible}
onVisibleChange={handleVisibleChange}
>
{props.button}
</Popover>
</div>
</div>
)
}
与setState非常相似,使用钩子的状态更新行为也需要重新渲染和更新,因此更改不会立即可见。但是,如果您尝试在handleVisibleChange方法之外记录状态,您将看到更新状态
export const NodeMenu: React.SFC<NodeMenuProps> = props => {
const [isVisible, setIsVisible] = useState(false)
const hide = () => {
setIsVisible(false)
}
const handleVisibleChange = (visible: boolean) => {
console.log(visible) // visible is `true` when user clicks. It works
setIsVisible(visible) // This does not set isVisible to `true`.
}
console.log({ isVisible });
return (
<div className={props.className}>
<div className={styles.requestNodeMenuIcon}>
<Popover
content={props.content}
title={props.title}
trigger="click"
placement="bottom"
visible={isVisible}
onVisibleChange={handleVisibleChange}
>
{props.button}
</Popover>
</div>
</div>
)
}
根据状态是否更新,您需要采取的任何操作都可以使用类似于的useEffect
挂钩来完成
useEffect(() => {
// take action when isVisible Changed
}, [isVisible])