(现代)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 = &lt;Inner ... /&gt;; const button = &lt;button onClick=inner.doTheThing() .../&gt;,对吧? (我还没有尝试过。)但你是对的:我意识到这可能是一个 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 组件而不会出现错误:不变的“你不应该在路由器外部使用链接”

关于react的一些须知

使用 React 在父组件中公开子组件的状态和方法

Coffeescript - 单击后React setState不呈现

react2