一种从外部调用 React 组件方法的方法(使用它的状态和道具)

Posted

技术标签:

【中文标题】一种从外部调用 React 组件方法的方法(使用它的状态和道具)【英文标题】:A way to call React component's method from outside (with it's state and props) 【发布时间】:2021-03-18 03:54:35 【问题描述】:

我一直在调用我的 clickRemoveHandler。这个想法是我有两个组件:第一个 - 呈现页眉、导航和页脚组件的布局,第二个 - 计算器,它是我的核心组件,具有数据输入等......在计算器组件中,我有托管状态的按钮,所以当我点击布局组件(div)上的任何地方,我都需要调用操纵我的按钮的计算器函数。 代码如下:

class Layout extends Component 
.....
    clickHandler = (event) => 
        Calculator.clickRemoveHandler(event);
        console.log('Clikced')
    ;
.....

class Calculator extends Component 
  state = 
    currentServiceClass: null,
    hoverIndex: null,
    btnClicked: false,
    selectedService: null
  
  currentCursorPosition = 
    el: null,
    index: null,
    rendered: false
  
  static clickRemoveHandler = (event) => 
    if ((!event.target.hasAttribute("type")) && (this.state.btnClicked)) 
      this.currentCursorPosition = 
        el: null,
        index: null,
        rendered: false
      ;
      this.setState(currentServiceClass: null, hoverIndex: null, btnClicked: false)
    
  
....

这些组件中有很多逻辑,因此它们过于健壮,无法发布完整代码。 但问题是布局中没有计算器引用,计算器本身是使用另一个组件的路由呈现的,所以我不能将布局中的任何数据直接传递给计算器。 我想要的是从布局中调用静态 clickRemoveHandler。正如我猜想的那样,静态是使函数全局化的一个选项。所以它可以工作,但我收到一个错误 TypeError: undefined is not an object (evalating 'Calculator.state.btnClicked')。如我所见,这意味着当调用 clickRemoveHandler 时,它与 Calculator 组件无关,或者无法访问其状态和道具。 问题是我怎样才能让这一切一起工作?调用函数时传递计算器状态还是有另一种更优雅的方法?

【问题讨论】:

在这里你可以找到一些答案***.com/questions/37949981/… 【参考方案1】:

我会建议您描述的情况(不同级别的不同组件需要访问某些状态并对其进行操作)使用 React context。您还可以查看ReduxMobX 等状态管理器,但在这种特殊情况下,由于您的应用程序不是那么“庞大”,因此会产生开销。基本上你需要创建一些单独的文件夹(你可以称之为context),在其中你应该创建上下文本身,导出它并将它包装在你最上层的组件中,这样所有的孩子都可以使用它。

您可以在此处找到示例:https://codesandbox.io/s/spring-glitter-0vzul。

这里是文档链接:https://reactjs.org/docs/context.html

如果您需要,我可以为您提供更多详细信息

【讨论】:

感谢您的回答!【参考方案2】:

这是一个挑战,但我做到了! 布局组件:

state = 
    firstMount: false,
    clicked: false,
    clickedEvt: null
;
clickHandler = (event) => 
    console.log('Clikced')
    if (this.state.clickedEvt) 
        this.setState(clicked: false, clickedEvt: null);
    else         
        this.setState(clicked: true, clickedEvt: event.target, ()=>setTimeout(() => 
            this.setState(clicked: false, clickedEvt: null)
        , 50))

;
        <LayoutContext.Provider value=
            clicked: this.state.clicked,
            clickedEvt: this.state.clickedEvt,
            handleClick: this.clickHandler
        >

render() 
    return(
        <div onClick=(event) => this.clickHandler(event) className="web">

首先我从布局组件调用handleClick作为onclick事件,然后从计算器再次调用它

  componentDidUpdate() 
    if (this.context.clicked) 
      this.clickRemoveHandler(this.context.clickedEvt)
    
  

【讨论】:

以上是关于一种从外部调用 React 组件方法的方法(使用它的状态和道具)的主要内容,如果未能解决你的问题,请参考以下文章

React Native - 在功能组件中创建方法并在组件外部调用此方法,可能吗?

从外部源动态加载 React 组件/捆绑包

如何在组件外部访问React Context?

React set Hook 从组件外部的函数调用

react.js 时钟组件

寻找一种从传入的 http 请求中获取 HTTP Digest Authentication 标头的方法