简体   繁体   English

如何在反应中从父组件调用子组件方法?

[英]How to call child component method from parent component in react?

There's an array of react components inside parent component.父组件中有一系列反应组件。 On some event on parent component I'd like to run through the array of child components and call a method for each.在父组件上的某些事件上,我想遍历子组件数组并为每个子组件调用一个方法。 How can I achieve that?我怎样才能做到这一点? It seems it doesn't work as in vanilla JS where you have an instance for the class and simply call a method.似乎它不像在香草 JS 中那样工作,你有一个 class 的实例并简单地调用一个方法。 So here's the simplified code:所以这里是简化的代码:

const Item = props => {
  const value = () => 'result!';
  return (
        <div></div>
  )
}
 
const App = props => {
  const items = props.items.map(item => <Item key={uuid()} item={item} />)
  const run = e => {
    items.map(item => console.log(item.value()))
  }
  return (
    <button onClick={run} type="button">Run!</button>
  ) 
}

const items = [
  'Lorem ipsum dolor sit amet',
  'consectetur adipiscing elit'
];

ReactDOM.render(<App items={items} />, document.querySelector("#app"))

I've created a jsfiddle with this code - https://jsfiddle.net/jkLq26pg/37/ On the 11th string the method value() is called and it raises an error.我用这段代码创建了一个 jsfiddle - https://jsfiddle.net/jkLq26pg/37/在第 11 个字符串上,方法 value() 被调用并引发错误。 But logging item.props works and outputs props for each item.但是记录item.props可以工作并为每个项目输出道具。 Why methods are not called?为什么不调用方法? Please provide me with an advice how to make it work.请向我提供如何使其工作的建议。

In your case you have to map thru the array and attach a ref using callback ref .在您的情况下,您必须通过数组 map 并使用回调 ref 附加一个 ref Render the child component using forwardRef and use the useImperativeHandle hook to expose your function to the parent.使用forwardRef渲染子组件并使用useImperativeHandle挂钩将 function 暴露给父组件。

Working demo 工作演示

Code Snippet代码片段

const Item = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => ({
    value: () => "result!"
  }));

  return <div ref={ref} />;
});

const itemsz = ["Lorem ipsum dolor sit amet", "consectetur adipiscing elit"];
const App = props => {
  const ref = useRef({});

  const items = itemsz.map((item, index) => {
    return (
      <Item
        ref={r => (ref.current[index] = r)}
        key={index}
        item={item}
      />
    );
  });
  const run = e => {
    items.map((item, index) => console.log(ref.current[index].value()));
  };
  return (
    <>
      <h3>click run and see console log</h3>
      <button onClick={run} type="button">
        Run!
      </button>
      {items}
    </>
  );
};

Note - Try avoiding this kind of pattern.注意- 尽量避免这种模式。

One way to solve this problem is to write useEffect and call your item.value() logic inside that useEffect .解决此问题的一种方法是编写useEffect并在该useEffect中调用您的item.value()逻辑。 Your function will then be automatically called once your list has mounted to the DOM.一旦您的列表已安装到 DOM,您的 function 将被自动调用。 That is probably the right place to call your function because your list would have rendered inside the DOM and side effects can then be handled.这可能是调用 function 的正确位置,因为您的列表将在 DOM 内呈现,然后可以处理副作用。

const Item = props => {
  const value = () => 'result!';

  // Handle your side effects here
  useEffect(() => {
    value();
  }, []);

  return (
        <div></div>
  )
}

This useEffect will work after a component will mount into DOM Node.这个 useEffect 将在组件挂载到 DOM 节点后起作用。 You can always put your function in one of the lifecycle methods in class based components or hooks in functional components and call them from there according to your situation.您始终可以将 function 放在基于 class 的组件中的生命周期方法之一或功能组件中的挂钩中,并根据您的情况从那里调用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM