With the help of d3 and react.js, I am able to create d3 hierarchy tree
What I want to achieve is, On click of each node text (eg John, Luke, ...) it should route to detail page of each clicked text.
nodes
.append("text")
.attr("font-size", "17px")
.attr("text-anchor", "start")
.text(function (d) {
return `${d.data.name}`
})
.on("click", function (event, d) {
this.props.history.push(`/detail/${d.id}`);
});
constructor
constructor(props) {
super(props);
console.log(this.props) // there is history in props
this.state = {
isClicked: ""
};
this.geGraph = this.getGraph.bind(this); // function where graph code presents
after clicking the node text. I getting error.
Uncaught TypeError: Cannot read properties of undefined (reading 'history')
Also when I debug on line this.props.history.push
, there is no props
in this
.
Tried to follow this How to use React Router with d3.js Graphs to redirect to another screen . still got the same issue. and when i try to go for arrow function
.on("click", (event, d) => this.props.history.push(`/detail/${d.id}`))
it gives issue for props this time Uncaught TypeError: Cannot read properties of undefined (reading 'props')
I have added history in <Route history={createBrowserHistory()}/>
as well import { createBrowserHistory } from "history";
. and did export default withRouter(MyGraph)
imported from import { withRouter } from 'react-router-dom';
.
I m using router version "react-router-dom": "^4.3.1"
and class based components.
How do I resolve this issue.
Thanks in advance!
CodePudding user response:
Your are using this on different scope, its scope is functional now, its better to define a function for click inside component and call it on click event.
Or you can store this value in another variable inside nodes creation scope and use it from that.
CodePudding user response:
According to the javascript DOM API documentation, the reference to this
will be the DOM element you will click on.
nodes
.append("text")
.attr("font-size", "17px")
.attr("text-anchor", "start")
.text(function (d) {
return `${d.data.name}`
})
.on("click", function (event, d) {
// try console.log here
console.log(this); // <--- most likely be a DOM element you clicked
this.props.history.push(`/detail/${d.id}`); // <--- therefore this.props does not exist
});
Solution 1
use either Javascript arrow function:
.on("click", (event, d) => {
console.log(this); // <--- this should refer to the parent object
this.props.history.push(`/detail/${d.id}`);
});
Solution 2
or bind the click event handler in the constructor with this
constructor(props) {
super(props);
console.log(this.props)
this.state = {
isClicked: ""
};
this.geGraph = this.getGraph.bind(this);
this.nodeClickHandler = this.nodeClickHandler.bind(this);
}
function nodeClickHandler (event, d) {
this.props.history.push(`/detail/${d.id}`);
}
nodes
.append("text")
.attr("font-size", "17px")
.attr("text-anchor", "start")
.text(function (d) {
return `${d.data.name}`
})
.on("click", this.nodeClickHandler);