reactjs - ReactJS:从另一个子组件调用子方法?
问题描述
我使用 ReactJS 16.12 并具有三个组件。1)父 2)历史 3)SvgViewer 。我想从 SvgViewer 功能组件(另一个子组件)调用一个属于历史组件(一个子组件)的函数。感谢您的解决方案...
这是我的代码:
1)父组件:
import React, { PureComponent } from "react";
import History from "./history";
import SvgViewer from "./svg-viewer";
class UnitMonitor extends PureComponent {
constructor() {
super();
this.History = React.createRef();
}
render() {
return (
<Row type="flex" className="">
<Col span={25}>
<History ref={this.History} />
<SvgViewer
svgFilePath={this.state.svgFilePath}
nodesData={this.state.nodes}
/>
</Col>
</Row>
);
}
}
export default UnitMonitor;
2)历史:
import React, { Component } from "react";
import {Modal } from "antd";
class History extends Component {
state = {
modalVisible: false,
tableData: [{}]
};
//i need call this method //
modalHistoryShow = nodeId => {
axios.get("api/tag-values/get-history/" + nodeId).then(response => {
this.setState({ tableData: response.data });
console.log(this.state.tableData);
});
this.setState({ modalVisible: true });
};
render(){
return (
<Modal
visible={this.state.modalVisible}
name="modalHistory"
footer={[null]}
width={"1000px"}
>
</Modal>
);
}
}
export default History;
3)SVG查看器:
import React, { useEffect, useState } from "react";
import * as d3 from "d3";
const SvgViewer = ({ nodesData, svgFilePath }) => {
const [svgContainer, setSvgContainer] = useState(undefined);
const showNodesOnSvg = nodes => {
//this.setState({ objectLoading: false });
//let nodesData = UnitMonitor.state.nodes;
let svgDoc = svgContainer.contentDocument;
let gTags = svgDoc.querySelectorAll("svg > g");
let container = null;
if (gTags.length > 1) container = svgDoc.querySelector("g:nth-of-type(2)");
else container = svgDoc.querySelector("g:nth-of-type(1)");
let node = d3.select(container);
nodesData.forEach(nodeData => {
node
.append("text")
.attr("id", "node" + nodeData["id"])
.attr("fill", "white")
.attr("text-anchor", "middle")
.attr("x", nodeData["positionX"])
.attr("y", nodeData["positionY"])
.attr("class", "clickable-node")
.style("font-size", "8px")
.style("position", "absolute")
.style("cursor", "pointer")
.style("display", "inline-block")
.on("click", function() {
clickHandler(nodeData["id"]);
})
.text("N/A" + " " + nodeData["symbol"]);
let nodeCreated = d3.select(
svgDoc.getElementById("node" + nodeData["id"])
);
nodeCreated
.append("title")
.attr("id", "title" + nodeData["id"])
.text(" " + nodeData["tagCode"]);
});
};
const clickHandler = nodeID => {
History.ModalHistoryShow(nodeID); // i need call ModalHistoryShow() this way
};
useEffect(() => {
const svg = document.querySelector("#svgobject");
setSvgContainer(svg);
svg.onload = () => {
if (nodesData != null) {
showNodesOnSvg();
}
};
});
return (
<div className="unit-schema-container1" key={svgFilePath}>
<object id="svgobject" type="image/svg+xml" data={svgFilePath}></object>
</div>
);
};
export default SvgViewer;
解决方案
可能是我的回答是最通用的,但我认为我认为最好的选择是以下两件事之一:-
- 将 nodeId 传递给 history 组件并在 History 组件中使用 useEffect Hook 并使用 nodeId 作为依赖项,以便每次 node Id 更改您在 useEffect 中的代码都会执行。例如-
useEffect(()=>{
// your logic to execute goes here
},[nodeId])
- 创建一个自定义钩子,让您从历史组件中提取代码,然后可以从您的代码的任何地方调用相同的钩子,这样您的代码就可以重用。
推荐阅读
- reactjs - 如何解决:setState 在 gastby 中不起作用?
- php - 在 Lando 环境中编辑后自动加载的 php 代码未更新
- sql - 将空值设置为重复行,然后仅保留 1 行
- flask - 将我的本地烧瓶服务器配置为可用于同一 wifi 网络下的其他设备
- codeigniter - 付款表单操作在本地主机上工作,但在服务器上不起作用
- flutter - 多个浮动按钮 - Flutter
- javascript - 借助包装函数消除异步函数中的 try-catch 块
- mysql - 计算月平均值
- nuget - 尝试安装 ZXing.Net 库时,NuGet 包管理器控制台返回 InvalidOperation
- c# - EF Core 3.0 .Include 不能按预期工作并且超级慢