在 React 和 Typescript 中,如何使 class 组件方法可以在组件外部访问?
How do I make a class component method accessible outside of the component in React and Typescript?
我需要能够在 class 之外调用 class 组件的方法,因为我正在构建一个编译为 umd
的组件库,然后可以通过 window
对象。
目前我的 classes 中的方法是私有的,但我想从外部创建它们 'callable'。我已经看到它可以使用 React refs
来完成,但我只能找到具体的示例,其中 ref
用于使 classes 方法可用于其他组件。
import React, { Component, ReactElement } from 'react';
interface DashboardProps {
props?: Function;
}
interface DashboardState {
ColorToggled: boolean;
myRef?: Function;
current?: Function;
}
class Dashboard extends Component<DashboardProps, DashboardState> {
private myRef: React.RefObject<HTMLInputElement>;
constructor(props: DashboardProps) {
super(props);
this.myRef = React.createRef();
this.state = {
colorToggled: false,
};
}
public changeColor = (): void => { // I want to make this method accessible outside of the component
this.setState((prevState) => ({
colorToggled: !prevState.colorToggled,
}));
};
render(): ReactElement {
// console.log(this.current.myRef();
return (
<>
<div
role="textbox"
tabIndex={0}
style={{
padding: '20px',
backgroundColor: this.state.colorToggled === true ? '#f00' : '#00f',
}}
>
<br />
</div>
<input type="text" ref={this.myRef} />
</>
);
}
}
export default Dashboard;
我才刚刚开始将以上内容放在一起,所以它根本不起作用,但不太确定如何进行。
在组件库中,几乎总是将一个或多个组件(如 Dashboard
)导出为一个模块(在您的情况下,UMD 也在全局范围内),并且包使用者提供 React 运行时。这也意味着,您可以依赖库中的 React 环境——只需将 props 从客户端传递给您的根组件。
如果您真的想从另一个组件强制调用 class 组件上的 public 方法,您可以使用 refs 来实现。
采用 public changeColor
方法的仪表板:
class Dashboard extends React.Component<{}, State> {
...
changeColor = (): void => {
this.setState(prevState => ({
colorToggled: !prevState.colorToggled
}));
};
}
(对于函数组件有 useImperativeHandle)
向仪表板添加引用并调用 changeColor
:
const App = () => {
let compRef = React.createRef<ColorComp>();
return (
<div>
<button onClick={() => compRef.current!.changeColor()}>
Toggle color
</button>
<ColorComp ref={compRef} />
</div>
);
};
可能还有更多选择,仅举几例:
- Custom DOM events (compare Microfrontends),
- window.postMessage window 个对象之间的通信,
- 在
componentDidMount
中的 window
上注册方法回调
这些必须以某种方式证明是合理的,因为它们增加了架构的复杂性和耦合性。所以我会坚持第一部分(通过 props and/or refs),除非你真的有特殊要求。
希望对您有帮助。
我需要能够在 class 之外调用 class 组件的方法,因为我正在构建一个编译为 umd
的组件库,然后可以通过 window
对象。
目前我的 classes 中的方法是私有的,但我想从外部创建它们 'callable'。我已经看到它可以使用 React refs
来完成,但我只能找到具体的示例,其中 ref
用于使 classes 方法可用于其他组件。
import React, { Component, ReactElement } from 'react';
interface DashboardProps {
props?: Function;
}
interface DashboardState {
ColorToggled: boolean;
myRef?: Function;
current?: Function;
}
class Dashboard extends Component<DashboardProps, DashboardState> {
private myRef: React.RefObject<HTMLInputElement>;
constructor(props: DashboardProps) {
super(props);
this.myRef = React.createRef();
this.state = {
colorToggled: false,
};
}
public changeColor = (): void => { // I want to make this method accessible outside of the component
this.setState((prevState) => ({
colorToggled: !prevState.colorToggled,
}));
};
render(): ReactElement {
// console.log(this.current.myRef();
return (
<>
<div
role="textbox"
tabIndex={0}
style={{
padding: '20px',
backgroundColor: this.state.colorToggled === true ? '#f00' : '#00f',
}}
>
<br />
</div>
<input type="text" ref={this.myRef} />
</>
);
}
}
export default Dashboard;
我才刚刚开始将以上内容放在一起,所以它根本不起作用,但不太确定如何进行。
在组件库中,几乎总是将一个或多个组件(如 Dashboard
)导出为一个模块(在您的情况下,UMD 也在全局范围内),并且包使用者提供 React 运行时。这也意味着,您可以依赖库中的 React 环境——只需将 props 从客户端传递给您的根组件。
如果您真的想从另一个组件强制调用 class 组件上的 public 方法,您可以使用 refs 来实现。
采用 public changeColor
方法的仪表板:
class Dashboard extends React.Component<{}, State> {
...
changeColor = (): void => {
this.setState(prevState => ({
colorToggled: !prevState.colorToggled
}));
};
}
(对于函数组件有 useImperativeHandle)
向仪表板添加引用并调用 changeColor
:
const App = () => {
let compRef = React.createRef<ColorComp>();
return (
<div>
<button onClick={() => compRef.current!.changeColor()}>
Toggle color
</button>
<ColorComp ref={compRef} />
</div>
);
};
可能还有更多选择,仅举几例:
- Custom DOM events (compare Microfrontends),
- window.postMessage window 个对象之间的通信,
- 在
componentDidMount
中的
window
上注册方法回调
这些必须以某种方式证明是合理的,因为它们增加了架构的复杂性和耦合性。所以我会坚持第一部分(通过 props and/or refs),除非你真的有特殊要求。
希望对您有帮助。