使用ref / forwardRef从另一个挂钩的组件调用函数

时间:2019-11-26 17:25:05

标签: reactjs react-hooks react-forwardref

我试图从另一个组件中调用一个函数,以老式的React Class样式,我能够轻松做到这一点,因为我试图钩住我所面临的所有此类问题

当我们使用引用调用setText()时,此代码不起作用:

export function MyComp(props, ref) {
  const [theText, setText] = useState(props.theText);

  return (
    <div>
      <h1>{theText}</h1>
      <button
        onClick={e => {
          setText("clicked with inside button");
        }}
      >
        inside button
      </button>
      <button
        onClick={e => {
          setText("not clicked");
        }}
      >
        reinit
      </button>
    </div>
  );
}

export const MyRefComp = React.forwardRef((props, ref) => (
  <MyComp ref={ref} {...props}>
    {props.children}
  </MyComp>
));

function App() {
  const compref = useRef();

  return (
    <div>
      <MyRefComp ref={compref} theText="not clicked" />
      <button
        onClick={e => {
          compref.current.setText("clicked with outside button");
        }}
      >
        outside button
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

这是可编辑的代码:https://codesandbox.io/s/reactforwardrefproblem-ublk0

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

这是您问题的答案,但我认为这样做不是一个好的模式。

您需要说明您要做什么,以便我们为您提供帮助。我认为您需要上下文或HOC。

Working example

答案 1 :(得分:0)

感谢@RTW, 我尝试了多少组合,但我却没有做过,这简直令人难以置信。 上下文或HOC不适合我的情况。 我还简化了它以避免中间组件,并允许对包含func的对象进行多次调用。 就是这里

const MyComp = React.forwardRef((props, ref) => {
  const [theText, setText] = useState(props.theText);
  ref.current = { setText: setText };

  return (
    <div>
      <h1>{theText}</h1>
      <button
        onClick={e => {
          setText("clicked with inside button");
        }}
      >
        inside button
      </button>
      <button
        onClick={e => {
          setText("not clicked");
        }}
      >
        reinit
      </button>
    </div>
  );
});

function App() {
  let compref = useRef();

  return (
    <div>
      <MyComp ref={compref} theText="not clicked" />
      <button
        onClick={e => {
          compref.current.setText("clicked with outside button");
        }}
      >
        outside button
      </button>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));

https://codesandbox.io/s/react-example-x194f