gpt4 book ai didi

javascript - 将流类型 React 组件转换为 JSX - React

转载 作者:行者123 更新时间:2023-12-02 22:00:47 25 4
gpt4 key购买 nike

我需要 React 中的可访问工具提示组件,并遇到了 React Tooltip 。它是用 flow 编写的,但我在构建中使用 jsx。我想将语法转换为 jsx,但在渲染方法中遇到了障碍。请建议我需要改变什么。

流程工具提示:https://pastebin.com/EfQQBKZ0

// @flow

import React, { Component } from 'react';
import type { ElementProps, ComponentType } from 'react';

export type LabelProps = {
labelAttributes: {
tabIndex: '0',
'aria-describedby': string,
onFocus: () => void,
},
isHidden: boolean,
};

export type OverlayProps = {
overlayAttributes: {
role: 'tooltip',
tabIndex: '-1',
id: string,
'aria-hidden': string,
},
isHidden: boolean,
};

export type TooltipState = {
isFocused: boolean,
isHovered: boolean,
};

export type TooltipProps = ElementProps<'div'> & {
label: ComponentType<LabelProps>,
overlay: ComponentType<OverlayProps>,
};

let counter = 0;

class Tooltip extends Component<TooltipProps, TooltipState> {
constructor(props: TooltipProps) {
super(props);
this.identifier = `react-accessible-tooltip-${counter}`;
counter += 1;
}

state = {
isFocused: false,
isHovered: false,
};

componentDidMount() {
document.addEventListener('keydown', this.handleKeyDown);
document.addEventListener('touchstart', this.handleTouch);
}

componentWillUnmount() {
document.removeEventListener('keydown', this.handleKeyDown);
document.removeEventListener('touchstart', this.handleTouch);
}

onFocus = () => {
this.setState({ isFocused: true });
};

onBlur = ({
relatedTarget,
currentTarget,
}: SyntheticFocusEvent<HTMLElement>) => {
// relatedTarget is better for React testability etc, but activeElement works as an IE11 fallback:
const newTarget = relatedTarget || document.activeElement;

// The idea of this logic is that we should only close the tooltip if focus has shifted from the tooltip AND all of its descendents.
if (!(newTarget && newTarget instanceof HTMLElement)) {
this.setState({ isFocused: false });
} else if (!currentTarget.contains(newTarget)) {
this.setState({ isFocused: false });
}
};

onMouseEnter = () => {
this.setState({ isHovered: true });
};

onMouseLeave = () => {
this.setState({ isHovered: false });
};

// This handles the support for touch devices that do not trigger blur on 'touch-away'.
handleTouch = ({ target }: Event) => {
const { activeElement } = document;

if (
activeElement instanceof Element &&
target instanceof Element &&
this.container instanceof Element &&
!this.container.contains(target) && // touch target not a tooltip descendent
this.state.isFocused // prevent redundant state change
) {
this.setState({ isFocused: false });
activeElement.blur();
} else if (
activeElement instanceof Element &&
target instanceof Element &&
this.container instanceof Element &&
this.container.contains(target) && // touch target is on tooltip descendant
!this.state.isFocused // prevent redundant state change
) {
this.setState({ isFocused: true });
}
};

handleKeyDown = ({ key, keyCode, which }: KeyboardEvent) => {
if (key === 'Escape' || keyCode === 27 || which === 27) {
this.setState({ isFocused: false });
}
};

container: ?HTMLDivElement;
identifier: string;

render() {
const { label: Label, overlay: Overlay, ...rest } = this.props;

const { isFocused, isHovered } = this.state;
const isHidden = !(isFocused || isHovered);

const labelProps: LabelProps = {
labelAttributes: {
tabIndex: '0',
'aria-describedby': this.identifier,
onFocus: this.onFocus,
},
isHidden,
};

const overlayProps: OverlayProps = {
overlayAttributes: {
role: 'tooltip',
tabIndex: '-1',
id: this.identifier,
'aria-hidden': isHidden.toString(),
},
isHidden,
};

return (
<div
{...rest}
onBlur={this.onBlur}
ref={ref => {
this.container = ref;
}}
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
>
<Label {...labelProps} />
<Overlay {...overlayProps} />
</div>
);
}
}

export default Tooltip;

JSX 工具提示:https://pastebin.com/QhQqRw24

import React, { Component } from 'react';
import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import InfoIcon from '../../InfoIcon/InfoIcon';

let counter = 0;

class TooltipContainer extends Component {
constructor(props) {
super(props);
this.state = {
isFocused: false,
isHovered: false,
};
this.identifier = `react-accessible-tooltip-${counter}`;
counter += 1;
this.onFocus = this.onFocus.bind(this);
this.onBlur = this.onBlur.bind(this);
this.onMouseEnter = this.onMouseEnter.bind(this);
this.onMouseLeave = this.onMouseLeave.bind(this);
this.handleTouch = this.handleTouch.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
this.container = React.createRef();
}

componentDidMount() {
document.addEventListener('keydown', this.handleKeyDown);
document.addEventListener('touchstart', this.handleTouch);
}

componentWillUnmount() {
document.removeEventListener('keydown', this.handleKeyDown);
document.removeEventListener('touchstart', this.handleTouch);
}

onFocus() {
this.setState({ isFocused: true });
};

onBlur({
relatedTarget,
currentTarget,
}){
// relatedTarget is better for React testability etc, but activeElement works as an IE11 fallback:
const newTarget = relatedTarget || document.activeElement;

// The idea of this logic is that we should only close the tooltip if focus has shifted from the tooltip AND all of its descendents.
if (!(newTarget)) {
this.setState({ isFocused: false });
} else if (!currentTarget.contains(newTarget)) {
this.setState({ isFocused: false });
}
}

onMouseEnter() {
this.setState({ isHovered: true });
}

onMouseLeave() {
this.setState({ isHovered: false });
}

// This handles the support for touch devices that do not trigger blur on 'touch-away'.
handleTouch({ target }) {
const { activeElement } = document;

if (
activeElement instanceof Element &&
target instanceof Element &&
this.container instanceof Element &&
!this.container.contains(target) && // touch target not a tooltip descendent
this.state.isFocused // prevent redundant state change
) {
this.setState({ isFocused: false });
activeElement.blur();
} else if (
activeElement instanceof Element &&
target instanceof Element &&
this.container instanceof Element &&
this.container.contains(target) && // touch target is on tooltip descendant
!this.state.isFocused // prevent redundant state change
) {
this.setState({ isFocused: true });
}
}

handleKeyDown({ key, keyCode, which }) {
if (key === 'Escape' || keyCode === 27 || which === 27) {
this.setState({ isFocused: false });
}
}


render() {
console.log('props', this.props)
const { label: Label, overlay: Overlay, ...rest } = this.props;

const { isFocused, isHovered } = this.state;
const isHidden = !(isFocused || isHovered);

const labelProps = {
labelAttributes: {
tabIndex: '0',
'aria-describedby': this.identifier,
onFocus: this.onFocus,
},
isHidden,
};

const overlayProps = {
overlayAttributes: {
role: 'tooltip',
tabIndex: '-1',
id: this.identifier,
'aria-hidden': isHidden.toString(),
},
isHidden,
};

return (
<div
{...rest}
onBlur={this.onBlur}
ref={ref => {
this.container = ref;
}}
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
>
<a><InfoIcon icon={faInfoCircle} {...labelProps} /></a>
<Overlay {...overlayProps} />
</div>
);
}
}

export default TooltipContainer;

最佳答案

我只是不明白,为什么你不想只安装该包并按照 API 描述使用它。

与你的问题相关,Flow只是一个类型检查器,如果你想摆脱它,只需从代码中删除与flow相关的东西即可。

我发现您做了一些与流程更改无关的操作,例如 refs.在您的流程示例中,有一个回调引用,但在没有流程的示例中,您尝试使用新的引用 API,但仍将其用作回调引用。这是第一眼看上去,还有更多其他的东西......

加上

roadblock in the render

听起来没有提供任何信息,您遇到了什么问题。

关于javascript - 将流类型 React 组件转换为 JSX - React,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59886500/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com