(现代)React 功能组件可以在外部公开有状态方法吗?
Posted
技术标签:
【中文标题】(现代)React 功能组件可以在外部公开有状态方法吗?【英文标题】:Can a (modern) React functional component expose a stateful method externally? 【发布时间】:2021-12-27 22:41:30 【问题描述】:我的 React 功能组件可以在外部公开一个可以访问内部状态的方法吗?
interface Inner
foo: string
function Inner(props: Inner)
const [foo, setFoo] = useState<string>(props.foo + "baz")
function doTheThing()
console.log(`doin' that $foo thing`)
return <div>props.foo</div>
function Outer()
const inner = <Inner foo="bar" />
return (
<>
<button onClick=() => inner.doTheThing()>
Do That Thing
</button>
inner
</>
)
这当然会给我一个错误:TypeError: inner.doTheThing is not a function
。
我可以使用类组件来公开这样的方法。但是有没有办法(用钩子?用 refs?)使这个工作与功能组件一起工作?
【问题讨论】:
您将如何使用类组件来做到这一点?使用new Inner
?无论如何,这是答案所在的问题之一 - 你以错误的方式解决这个问题。提升状态,如果由于某种原因这不是一个选项,那么请查看参考。
@BrianThompson 有了类组件,我想我可以这样做:const inner = <Inner ... />; const button = <button onClick=inner.doTheThing() .../>
,对吧? (我还没有尝试过。)但你是对的:我意识到这可能是一个 React 反模式,或者至少不是标准做法。在我的实际用例中,我包装了一个现成的组件来执行我需要的doTheThing
;不写doTheThing
自己,这是我在这里试图避免的,我不知道如何在不暴露这样的方法的情况下解决它。
不,这也不适用于类组件。一旦你添加了 JSX 语法(正如你应该做的那样),你使用的不是一个类实例,而是一个具有该类的 type 的 React 元素。如果您无法访问具有所需功能的组件,并且它还没有以某种方式公开,那么就没有办法获得它。
【参考方案1】:
您可以传递一个 ref,然后将 doTheThing
引用存储在那里。
import MutableRefObject, useRef, useState from "react";
interface Inner
foo: string;
dRef: MutableRefObject< doTheThing: () => void | undefined>;
function Inner(props: Inner)
const [foo, setFoo] = useState<string>(props.foo + "baz");
function doTheThing()
console.log(`doin' that $foo thing`);
props.dRef.current = doTheThing ;
return <div>props.foo</div>;
export function Outer()
const dRef = useRef< doTheThing: () => void >();
const inner = <Inner foo="bar" dRef=dRef />;
return (
<>
<button onClick=() => dRef.current?.doTheThing()>Do That Thing</button>
inner
</>
);
【讨论】:
您能否简要介绍一下引用可以访问Inner
状态变量的情况?
查看更新的答案
啊,酷。我的部分问题是试图将一个名为ref
的道具传递给Inner
;看起来您正在使用 dRef
以避免与 React 关键字发生冲突。
如果你真的想把它命名为ref
,那么你需要使用forwardRef
来正确处理它。以上是关于(现代)React 功能组件可以在外部公开有状态方法吗?的主要内容,如果未能解决你的问题,请参考以下文章
Service Fabric - 如何在外部公开 wcf 服务
如何在外部 npm 包中使用 React 的 Link 组件而不会出现错误:不变的“你不应该在路由器外部使用链接”