从父组件调用子组件函数

时间:2019-08-04 22:12:56

标签: reactjs

我想保持控件尽可能独立,因此需要我的父控件访问其孩子的功能。

这样的示例可能是其父级内部的列表子级组件,当添加了一条附加记录时,父级需要告诉子级重新获取其数据,或者页面上有模式控件并对其执行操作页面触发,并且父级需要调用模式显示函数。

向子组件添加一个ref并调用该方法可以工作但感觉不正确的方法,这将迫使您不使用无状态组件。第二种方法是将prop传递到子组件中,并对该子组件应用该函数也可以,但是如果导致子组件更新引用的父级更新可能丢失,因为引用只是局部变量。

const Parent = ({}) => {
  let childComponent = null;

  return (
    <React.Fragment>
      <button
        onClick={() => {
          childComponent.show({});
        }}
      />
      <Child
        recordId={recordId}
        permissions={permissions}
        actions={ref => (childComponent = ref)}
      />
    </React.Fragment>
  );
};

export default Parent;


const Child = ({  actions }) => {
  const [show, setShow] = useState(false);
  const [initValues, setInitValues] = useState(null);

  if (actions) {
    actions({
      show: data => {
        if (data) {
          setInitValues(data);
        }
        setShow(true);
      }
    });
  }
  return (
        <Modal size="md" isOpen={show} onClosed={() => handleHide()}>

        </Modal>
      )}

export default Child ;

处理此问题的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

像这样吗?

[CodePen Mirror]

原始:

// PARENT
function Parent(props) {
  const doChildMethod = event => {
    console.log("[Parent]::Invoked Child method from parent");
    alert(event.target.innerHTML);
  };
  
  return (
    <div style={{ border: "1px solid blue" }}>
      <p>PARENT</p>
      <Child iAmAChildMethod={e=>doChildMethod(e)} />
    </div>
  );
}

// CHILD
function Child(props) {
  const handleClick = event => {
    props.iAmAChildMethod(event);
    console.log("[Child]::Do whatever you want in the child");
  };

  return (
    <div style={{ border: "1px solid red", margin: "5px" }}>
      <p onClick={handleClick}>CHILD - CLICK ME</p>
    </div>
  );
}

ReactDOM.render(<Parent />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


已更新

请记住,这是一种反模式。

// Parent
const Parent = () => {
  let child;
  
  function getChildData(callbacks){
    child = callbacks;
  }

    return (
      <div>
        <button onClick={() => child.getData()}>Retreive Child Data</button>
        <Child onRetreiveChildData={callbacks => getChildData(callbacks)} />
      </div>
    );
}

// Child
const Child = ({ onRetreiveChildData }) => {
  const [state, setState] = React.useState({
    data: "Default Child Data"
  });

  if (onRetreiveChildData) {
    onRetreiveChildData({
      getData: () => getData("Data from Child: " + Math.random())
    });
  }
  
  function getData(data){
    setState({ data: data });
  };

  return (
    <pre>{state.data}</pre>
  )
};


ReactDOM.render(<Parent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>

<div id='root' style='width: 100%; height: 100%'>
</div>