首页 > 解决方案 > 如何将 API 响应从子组件传递到另一个嵌套组件?

问题描述

我有一个组件MockTable,我在其中获取 API 响应并存储到变量data中。我想在另一个组件中使用数据UsecasePane。我可以知道将数据传递给的正确方法UsecasePane吗?

=> MainContent.js

const MainContent = () => {
  return (
    <div >
      <CustomerTable />
      <AddMock />
      <MockTable />
    </div>
  );
};

export default MainContent;

现在TabContent是孩子AddMock

=> AddMock.js

const AddMock = () => {
  return (
    <div className="row">
              <Container className="mockbody">
                <Header as="h3">Hierarchy</Header>
                <TabContent />
              </Container>
    </div>
  );
};

export default AddMock;

UsecasePane嵌套在TabContent.

// 标签内容.js

import React from "react";
import { Tab } from "semantic-ui-react";
import UsecasePane from "./UsecasePane";

const panes = [
  {
    menuItem: "Usecase",
    render: () => <Tab.Pane attached={false}>{<UsecasePane />}</Tab.Pane>,
  }
];

const TabContent = () => (
  <Tab menu={{ secondary: true, pointing: true }} panes={panes} />
);

export default TabContent;

=> MockTable.js

import React, { useState, useEffect } from "react";
import "../assets/css/material-dashboard.css";
import axios from "axios";
import { Icon, Dimmer, Loader, Segment } from "semantic-ui-react";

let config = require("../appConfiguration");

const MockTable = () => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);

  const fetchData = async () => {
    const response = await axios
      .get(config.App_URL.getAllTest, {
        params: {
          customHostName: "suite",
          type: "routes",
        },
      })
      .catch((error) => {
        console.error(`Error in fetching the data ${error}`);
      });
    let list = [response.data];
    setData(list);
    setLoading(true);
  };

  useEffect(() => {
    fetchData();
  }, []);

  
return (
     // rest of the code
)
  
};
export default MockTable;

现在我需要传递这个UsecasePane嵌套在另一个组件中的数据TabContent

标签: javascriptreactjsreact-hooks

解决方案


有多种方法可以将数据传递给子组件。

  1. 使用道具

//In Grandparent
<Parent dataToParent={someData}/>

//In Parent 
<Child dataToChild={props.dataToParent}/>

//Using in Child
render(){
   {props.dataToChild}
}
  1. 渲染道具(跳过层次结构)

https://reactjs.org/docs/render-props.html

//In Grandparent component
<Parent dataToParent={dataFromParent => (
  <Child>{dataFromParent}</Child>
)}/>
  1. 将数据存储在中央状态

上下文 API:https ://reactjs.org/docs/context.html

第三方库:

即 Redux https://redux.js.org/

编辑:

感谢您更新问题。通过查看层次结构,您似乎正在处理兄弟组件。ieMainContent -> MockTable是您获取数据的MainContent -> AddMock -> TabContent -> UsecasePane位置以及您想要显示/传递数据的位置。对于这两者,直接的共同父级是MainContent.

如果您不想使用 ContextAPI 或任何其他第三方库。我建议提升您的状态MainContent并将回调函数传递给MockTable并将状态传递给MainContent -> AddMock -> TabContent -> UsecasePane

考虑以下示例:

//MainContent.js
const MainContent = () => {
  ...
  const [data, setData] = useState([]);
  ...
  return (
    <div >
      <CustomerTable />
      <AddMock setData={setData} /> {/*Passing callback function*/}
      <MockTable data={data} /> {/*Passing state*/}
    </div>
  );
};

export default MainContent;
//AddMock.js
...
const fetchData = async () => {
    // all data fetching logic remains the same.
    let list = [response.data];
    props.setData(list); //Calling callback function to set the state defined in MainContent.js
  };

useEffect(() => {
    fetchData();
  }, []);
...
//AddMock.js

const AddMock = ({data}) => {
  return (
    <div className="row">
              <Container className="mockbody">
                <Header as="h3">Hierarchy</Header>
                <TabContent data={data} /> {/*Passing data props*/}
              </Container>
    </div>
  );
};

export default AddMock;

//TabContent.js

const TabContent = ({data}) => {
const panes = [
  {
    menuItem: "Usecase",
    render: () => <Tab.Pane attached={false}>{<UsecasePane data={data} />}</Tab.Pane>,
  }
];
 return(
  <Tab menu={{ secondary: true, pointing: true }} panes={panes} />
 )
}

export default TabContent;
//

在这里你可以看到,为了传递数据,有些prop drilling事情正在发生,虽然这不是一种反模式,但建议在功能组件中尽可能避免,因为它们不支持,shouldComponentUpdate()否则React.PureComponent你可以使用React.memoHOC阅读更多

当然 React.Context 或第三方库,即 Redux(尽管对于小型应用程序来说它会被过度杀伤)是所有这些的替代品。


推荐阅读