React: 在点击选项卡时调用子组件的函数

huangapple go评论71阅读模式
英文:

React: Calling a child component's function when a tab is clicked

问题

App.js

import MyComponent from './MyComponent';
import React from 'react';
import './App.css';
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import 'react-tabs/style/react-tabs.css';

function App() {
  function handleTabSelect(index, last) {
    if (index === 1 && myComponentRef.current) {
      myComponentRef.current.funcA();
    }
  }

  const myComponentRef = React.useRef();

  return (
    <div className="App">
      <Tabs onSelect={handleTabSelect}>
        <TabList>
          <Tab>Tab 1</Tab>
          <Tab>Tab 2</Tab>
        </TabList>

        <TabPanel>
          HelloWorld123
        </TabPanel>
        <TabPanel>
          <MyComponent ref={myComponentRef} />
        </TabPanel>
      </Tabs>
    </div>
  );
}

export default App;

MyComponent.jsx as a child component.

import React from 'react';

const MyComponent = React.forwardRef((props, ref) => {
  function funcA() {
    console.log('Function A is called');
    myRef.current && myRef.current.focus();
  }

  // Save the ref to the DOM node you want to reference
  const myRef = React.useRef(null);
  React.useImperativeHandle(ref, () => ({
    funcA: funcA
  }));

  return (
    <div>
      <p ref={myRef}>This is a message for Tab 2</p>
    </div>
  );
});

export default MyComponent;

不包括代码的翻译部分已经提供。

英文:

I am trying to create a React app that has two tabs(Tab1, Tab2) and when you click on Tab2, a message saying 'Function A is called' will appear in the console.

But it does not work with the following code.
The tabs works fine but no message on the console.
How can I solve it?

App.js

import MyComponent from &#39;./MyComponent&#39;;
import React from &#39;react&#39;;
import &#39;./App.css&#39;;
import { Tab, Tabs, TabList, TabPanel } from &#39;react-tabs&#39;;
import &#39;react-tabs/style/react-tabs.css&#39;;

function App() {
  function handleTabSelect(index, last) {
    if (index === 1 &amp;&amp; myComponentRef.current) {
      myComponentRef.current.funcA();
    }
  }

  const myComponentRef = React.useRef();

  return (
    &lt;div className=&quot;App&quot;&gt;
      &lt;Tabs onSelect={handleTabSelect}&gt;
        &lt;TabList&gt;
          &lt;Tab&gt;Tab 1&lt;/Tab&gt;
          &lt;Tab&gt;Tab 2&lt;/Tab&gt;
        &lt;/TabList&gt;

        &lt;TabPanel&gt;
          HelloWorld123
        &lt;/TabPanel&gt;
        &lt;TabPanel&gt;
          &lt;MyComponent ref={myComponentRef} /&gt;
        &lt;/TabPanel&gt;
      &lt;/Tabs&gt;
    &lt;/div&gt;
  );
}


export default App;

MyComponent.jsx as a child component.

import React from &#39;react&#39;;

const MyComponent = React.forwardRef((props, ref) =&gt; {
  function funcA() {
    console.log(&#39;Function A is called&#39;);
    myRef.current &amp;&amp; myRef.current.focus();
  }

  // Save the ref to the DOM node you want to reference
  const myRef = React.useRef(null);
  React.useImperativeHandle(ref, () =&gt; ({
    funcA: funcA
  }));

  return (
    &lt;div&gt;
      &lt;p ref={myRef}&gt;This is a message for Tab 2&lt;/p&gt;
    &lt;/div&gt;
  );
});

export default MyComponent;

答案1

得分: 1

因为条件渲染,TabPanel-2 无法将任何内容转发到父组件。请参阅这里:https://beta.reactjs.org/reference/react/forwardRef#my-component-is-wrapped-in-forwardref-but-the-ref-to-it-is-always-null

至少有两种方法可以调用 funcA。

  1. 通过在 handleTabSelect 中使用 setTimeout 调用 funcA;当 TabPanel 在此渲染中显示时,setTimeout 将获取当前目标而不是 null。
setTimeout(() => {
  if (index === 1 && myComponentRef.current) {
    myComponentRef.current.funcA();
  }
}, 0);
  1. 将一个 prop 发送到 TabPanel-2 并使用 Effect 监视并调用 funcA。
const [index, setIndex] = useState(0)

function handleTabSelect(index, last) {
  setIndex(index)
}
<MyComponent index={index} />
useEffect(() => {
  if(props.index===1){
    funcA();
  }
}, [props.index])
英文:

Because of conditional render, TabPanel-2 can't forward anything to parent component. see here. https://beta.reactjs.org/reference/react/forwardRef#my-component-is-wrapped-in-forwardref-but-the-ref-to-it-is-always-null

At least two ways to call funcA.

  1. call funcA by setTimeout in handleTabSelect;While TabPanel Has render to display in this render ,setTimeout will get the current target instead of null.
 setTimeout(() =&gt; {
  if (index === 1 &amp;&amp; myComponentRef.current) {
    myComponentRef.current.funcA();
  }
}, 0);
  1. send a prop to TabPanel-2 and use Effect to watch and call funcA.
const [index, setIndex] = useState(0)
function handleTabSelect(index, last) {
  setIndex(index)
}
&lt;MyComponent index={index}  /&gt;
useEffect(() =&gt; {
  if(props.index===1){
    funcA();
  }
}, [props.index])

huangapple
  • 本文由 发表于 2023年2月18日 15:48:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75491926.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定