I am displaying a tree view on left frame of the page. Tree is generating from xml file. On the click of each node, components are opening in the right frame of the page. ProductsTreeView is the tree component, Add_Category is the component that will open on the click of one of the tree node. I am passing the props through routing. everything is working fine as long as the page not refresh. In case of page refresh, props is showing null in the Add_Category page. Please help how to fix this. [1]: https://i.stack.imgur.com/QeYB6.gif
App.js
import React, { Component } from 'react';
import { Switch, Route, BrowserRouter, Redirect } from "react-router-dom";
import Home from './components/Home';
export class App extends Component {
render() {
return (
<div>
<BrowserRouter>
<Switch>
<Route path="/" component={Home} />
<Redirect to="/" />
</Switch>
</BrowserRouter>
</div>
);
}
}
export default App;
_____________
Home.js
import React from 'react';
import { Route} from "react-router-dom";
import ProductsTree from '.ProductsTreeView';
import AddCategory from './Add_Category';
class Home extends React.Component
constructor(props) {
super(props);
this.state =
{
currentNode: {},
data: "",
};
this.setCurrentNode = this.setCurrentNode.bind(this);
}
setCurrentNode(node) {
this.setState({ currentNode: node });
}
render() {
return (
<div>
<table className="Container">
<tbody><tr width="100%">
<td className="TreeContainer">
<ProductsTree setCurrentNode={this.setCurrentNode} /> </td>
<td className="BodyContainer">
<Route path="/Add_Category">
<AddCategory key_id={this.state.currentNode.key_id} />
</Route>
</td> </tr> </tbody> </table>
</div>
);
}
}
export default Home;
_________________________
***Add_Category***
import React from 'react'
export class Add_Category extends React.Component {
constructor(props) {
super(props);
this.state = {
ID: "",
Name: "",
};
}
componentDidMount() {
if (typeof this.props.key_id !== 'undefined') {
const ID= this.props.key_id;
this.getName(ID);
}
}
componentDidUpdate(prevProps) {
if (prevProps.key_id !== this.props.key_id) {
console.log(`key_id: ${this.props.key_id}`);
const ID= this.props.key_id;
this.getName(ID);
}
}
async getName(ID) {
await fetch(REQUEST_URL)
.then(response => response.json())
.then((data) => {
this.setState({
Name: data,
ID: this.props.key_id,
loading: false})
console.log(this.state.Name)
})[![enter image description here][1]][1]
}
render() {
return (
<div>
<form>
{this.state.Name}
</form>
</div>
);
}
}
export default Add_Category;
_________________________
ProductsTreeView.js
import React, { Component } from 'react';
import ReactHtmlParser from 'react-html-parser';
import axios from 'axios';
import XMLParser from 'react-xml-parser';
import { Link } from "react-router-dom";
class ProductsTreeView extends Component {
render() {
return (
<div id="TreeView">
<TreeView setCurrentNode={this.props.setCurrentNode} />
</div>
);
}
}
class Node {
description = 'n/a';
id = -1;
key_id = -1;
linkpagename = '';
isActive = false;
nodes = [];
constructor(description, id, key_id, linkpagename) {
this.description = description;
this.id = id;
this.key_id = key_id;
this.linkpagename = linkpagename;
}
static nodesFromXml(xml) {
const map = (entity, nodes) => {
const id = entity.attributes['id'];
const key_id = entity.attributes['key-id'];
const descriptionText =
entity.children[
entity.children.findIndex((child) => child.name === 'description')
].value;
const entities = entity.children.filter(
(child) => child.name === 'entity'
);
var linkPageName = entity.attributes['link-page-name'];
linkPageName = linkPageName.replace(".aspx", "");
const node = new Node(descriptionText, id, key_id, linkPageName);
nodes.push(node);
entities.forEach((entity) => map(entity, node.nodes));
};
const parsedData = new XMLParser().parseFromString(xml);
const entities = parsedData.children.filter(
(child) => child.name === 'entity'
);
const nodes = [];
entities.forEach((entity) => map(entity, nodes));
return nodes;
}
}
class TreeView extends React.Component {
constructor(props) {
super(props);
this.state = { nodes: [] };
this.toggleNode = this.toggleNode.bind(this);
}
componentDidMount() {
axios
.get(REQUEST_URL, { 'Content-Type': 'application/xml; charset=utf-8' })
.then((response) =>
this.setState({ nodes: Node.nodesFromXml(response.data) }))
.catch(function (error) {
if (error.response) {
// Request made and server responded
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
console.log(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log('Error', error.message);
}
});
}
render() {
const nodes = this.state.nodes;
return (
<ul>
{nodes.map((node) => (
<TreeNode
id={node.id}
key={node.key_id}
node={node}
onToggle={this.toggleNode}
setCurrentNode={this.props.setCurrentNode}
/>
))}
</ul>
);
}
toggleNode(node) {
this.props.setCurrentNode(node);
function _toggleNode(currentNode, node) {
if (currentNode.id === node.id) { //currentNode.id === node.id)
{
if (currentNode.key_id === node.key_id)
{
currentNode.isActive = !currentNode.isActive;
}
}
}
else
{
currentNode.nodes.forEach((childNode) => _toggleNode(childNode, node));
}
}
const nodes = this.state.nodes;
nodes.forEach((currentNode) => _toggleNode(currentNode, node));
this.setState((state) => (state.nodes = nodes));
}
}
class TreeNode extends React.Component {
render() {
const node = this.props.node;
const onToggle = this.props.onToggle;
let activeChildren = null;
if (node.isActive && node.nodes.length > 0) {
activeChildren = (
<ul>
{node.nodes.map((node) => (
<TreeNode
id={node.id}
key={node.key_id}
node={node}
onToggle={onToggle}
/>
))}
</ul>
);
}
return (
<li
id={node.id} linkpagename={node.linkpagename}
key={node.key_id}
onClick={(event) => {
event.stopPropagation();
onToggle(node);
}}
>
<Link to={node.linkpagename} style={{ textDecoration: 'none', color: '#000000' }} >
{node.description}</Link>
{activeChildren}
</li>
);
}
}
export default ProductsTreeView;
thanks