【问题标题】:how to call function of child in functional component from parent in react.js?如何从react.js中的父级调用功能组件中子级的功能?
【发布时间】:2019-12-26 07:40:45
【问题描述】:

我有两个组件:

  1. 父母
  2. 孩子

父组件是类组件,子组件是功能组件。从父组件调用子方法的最佳做法是什么?

这些组件的目标是能够动态加载 svg 文件。

父组件:

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>
    );
  }
  };

子组件:

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;

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    在 React 中,尝试在父级上运行子方法并不是一个好主意,因为这主要是设计不佳的标志。由于您想动态运行 SVG,您可以传递一个带有路径的道具或您需要的内容以动态加载它。但是,如果您坚持在父级上运行该方法,请查看此post 以了解如何执行此操作。

    【讨论】:

    • 摘自“Programming .NET Components, 2nd Edition by Juval Lowy”——“简而言之,面向对象编程关注组合成一个大型二进制可执行文件的类之间的关系,而组件-面向编程专注于可互换的代码模块,它们独立工作,不需要你熟悉它们的内部工作来使用它们。” - 恕我直言,在孩子身上调用函数只是比 COP 更 OOP。但是通过它知道传递一个孩子的道具,你是否没有像函数名和要调用的参数一样给父母提供更多的知识?
    【解决方案2】:

    在父组件中定义所有函数并将其作为道具传递给子组件。

    试试这个

    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>
        );
      }
      };
    

    在子组件中这样访问

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

    img={props.image}
    

    【讨论】:

      【解决方案3】:

      使用临时道具。例如点击次数。在 useEffect hooks 方法中处理点击计数当 props.count 改变时,调用函数)

      在您的子组件中使用此代码段:

      useEffect(() =>Call your function is here, [props.count ]);
      

      【讨论】:

        【解决方案4】:

        您可以像这样创建功能性子组件:

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

        然后在你的父母中,你可以像这样调用子方法:

        import React, { useRef } from 'react';
        
        const Parent = () => {
            const childRef = useRef(null);
        
            useEffect(() => {
                if (childRef?.current) {
                    childRef.current.storeExpandedRecords();
                }
            }, []);
        
            return (
                <Child ref={childRef} />
            );
        };
        

        【讨论】:

          猜你喜欢
          • 2021-05-17
          • 2021-06-11
          • 1970-01-01
          • 2020-01-22
          • 2020-07-25
          • 1970-01-01
          • 2017-04-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多