我有一个组件MockTable
,我在其中获取 API 响应并存储到变量data
中。我想在另一个组件中使用数据UsecasePane
.我可以知道将数据传递给UsecasePane
的正确方法吗?
MockTable
是MainContent
的子组件。AddMock
是MainContent
的子组件。
=> 主要内容.js
const MainContent = () => {
return (
<div >
<CustomerTable />
<AddMock />
<MockTable />
</div>
);
};
export default MainContent;
现在TabContent
是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;
=>模拟表.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/
编辑:
感谢您更新问题。通过查看层次结构,您似乎正在处理同级组件。即MainContent -> 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(尽管对于小型应用程序来说会矫枉过正)是所有这些的几个替代品。
已编辑
尝试在 MainContent 中获取数据以集中数据,然后进行调度。使用回调 (addData) 将新数据传递给父级
主要内容
const MainContent = () => {
// get datas
function addData(newData){
setData([...data, newData])
}
return (
<div>
<CustomerTable />
<AddMock addData={addData} />
<MockTable data={data} />
</div>
);
};
添加模拟
const AddMock = (props) => {
// use props.addData(newData)
};
您可以创建一个将返回数组的函数,然后您可以将参数传递给该函数,该函数将在用例窗格中组件中使用。
const panes = (arg) => {
// do something with arg...
return [
{
menuItem: "Usecase",
render: () => <Tab.Pane attached={false}>{<UsecasePane arg={arg} />}</Tab.Pane>,
}
];
}
const TabContent = () => (
<Tab menu={{ secondary: true, pointing: true }} panes={ panes() } />
);