7

I have two components:

  1. parent
  2. child

The parent is class component and child is functional component. What is best practice to call child methods from the parent component?

The goal of these components is to be able to load svg file dynamically.

Parent component:

class UnitMonitor extends PureComponent {
  constructor() {
    super();
  }
  state = {
    img: null,
  };
  onChangeShcema = schemaID => {
    axios.get("/api/schemata/get-schemata-nodes/" + schemaID).then(response => {
      let path = response.data["0"]["file"];
      // call loadFile function of child component is needed
    });
render() {
    return (
      <Row type="flex" className="">
        <Col span={25}>
          <SvgViewer />
        </Col>
      </Row>
    );
  }
  };

Child Component:

const SvgViewer = () => {

  const loadFile = path => { 
    let svgFile = require("./images/" + path);
    const svg = document.querySelector("#svgobject");
    svg.setAttribute("data", svgFile);
  };

  return (
    <div className="unit-schema-container1">
      <object id="svgobject" type="image/svg+xml" data={null}></object>
    </div>
  );
};

export default SvgViewer;
Simon.S.A.
  • 6,240
  • 7
  • 22
  • 41
Rohullah Rajaee Rad
  • 571
  • 2
  • 9
  • 33

4 Answers4

3

In React it is not a good idea to try to run a child method on the parent since it is mainly a sign of a bad design. Since you want to run the SVG dynamically, you could pass a prop with the path or what you need in order to load it dynamically. However, if you are adamant in running the method on the parent check out this post on how to do it.

Jose Felix
  • 970
  • 5
  • 7
  • 2
    From "Programming .NET Components, 2nd Edition by Juval Lowy" -- "In a nutshell, object-oriented programming focuses on the relationships between classes that are combined into one large binary executable, while component-oriented programming focuses on interchangeable code modules that work independently and don’t require you to be familiar with their inner workings to use them." -- IMHO, calling a function on a child is just more OOP than COP. But by its knowing what props to pass a child, are you not giving the parent as much knowledge as a function name and args to be called? – Cliff Hall Jun 30 '20 at 16:12
1

Define all your function in parent component and pass that as props to child component.

Try this

class UnitMonitor extends PureComponent {
  constructor() {
    super();
  }
  state = {
    img: null,
  };
  onChangeShcema = schemaID => {
    axios.get("/api/schemata/get-schemata-nodes/" + schemaID).then(response => {
      let path = response.data["0"]["file"];
       this.setState({img: path});
      // call loadFile function of child component is needed
    });
render() {
    return (
      <Row type="flex" className="">
        <Col span={25}>
          <SvgViewer onChangeShcema ={this.onChangeShcema} image={this.state.img} />
        </Col>
      </Row>
    );
  }
  };

Access like this in child component

onChange={props.onChangeShcema} or onClick={props.onChangeShcema}

img={props.image}
akhtarvahid
  • 9,445
  • 2
  • 26
  • 29
1

Use temporary props. For example click count. Handle click count in useEffect hooks methods When props.count is changed, call function )

in your child component use this code segment:

useEffect(() =>Call your function is here, [props.count ]);
Ramil Aliyev 007
  • 4,437
  • 2
  • 31
  • 47
0

You can create a functional child component like this:

import React, { forwardRef, useImperativeHandle } from 'react';

export default forwardRef((props, ref) => {
    useImperativeHandle(ref,
        () => ({
            storeExpandedRecords () {
                console.log('Storing expanded records...');
            },
        }));
    return (
        <p>BryntumGrid</p>
    );
});

And then in your parent, you can call the child method like this:

import React, { useRef } from 'react';

const Parent = () => {
    const childRef = useRef(null);

    useEffect(() => {
        if (childRef?.current) {
            childRef.current.storeExpandedRecords();
        }
    }, []);

    return (
        <Child ref={childRef} />
    );
};
Yamo93
  • 514
  • 3
  • 12