javascript - 如何将 API 响应从子组件传递到另一个嵌套组件?
问题描述
我有一个组件MockTable
,我在其中获取 API 响应并存储到变量data
中。我想在另一个组件中使用数据UsecasePane
。我可以知道将数据传递给的正确方法UsecasePane
吗?
MockTable
是 的子组件MainContent
。AddMock
是 的子组件MainContent
。
=> 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
解决方案
有多种方法可以将数据传递给子组件。
- 使用道具
//In Grandparent
<Parent dataToParent={someData}/>
//In Parent
<Child dataToChild={props.dataToParent}/>
//Using in Child
render(){
{props.dataToChild}
}
- 渲染道具(跳过层次结构)
https://reactjs.org/docs/render-props.html
//In Grandparent component
<Parent dataToParent={dataFromParent => (
<Child>{dataFromParent}</Child>
)}/>
- 将数据存储在中央状态
上下文 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.memo
HOC阅读更多。
当然 React.Context 或第三方库,即 Redux(尽管对于小型应用程序来说它会被过度杀伤)是所有这些的替代品。