Reputation: 251
So I am completing this task where I convert raw html in to a react component, and I need to complete this task 4 times, for 4 menu's in the Navigation Bar. The code works, however the code looks ugly and I am sure there is a way to complete the tasks with less lines. The code which is repeated which I would like to be more efficient is the processinginstructions and processinginstructionsTwo. The code is here:
import React, { useState, useEffect } from "react";
import { Grid, Container } from "@material-ui/core";
import { navSubMenuStyles } from "./Styles";
import "./stylesheets/NavBar.css";
import NavBar from "./NavBar";
import NavMenuLink from "./stylesheets/NavMenuLink";
function NavBarContent() {
const pageName = ["HIDDEN-FOR-PRIVACY", "HIDDEN-FOR-PRIVACY"];
const [content, setContent] = useState();
const [contenttwo, setContenttwo] = useState();
async function fetchData() {
const res = await fetch("HIDDEN-FOR-PRIVACY" + pageName);
res
.json()
.then((res) => {
setContent(res[0].content.rendered.replace(/(\r\n|\n|\r)/gm, ""));
setContenttwo(res[1].content.rendered.replace(/(\r\n|\n|\r)/gm, ""));
})
.catch((err) => console.log(err));
}
useEffect(() => {
fetchData();
}, []);
var HtmlToReact = require("html-to-react");
var HtmlToReactParser = require("html-to-react").Parser;
var htmlInput = content;
var htmlInputTwo = contenttwo;
// Order matters. Instructions are processed in the order they're defined
var processNodeDefinitions = new HtmlToReact.ProcessNodeDefinitions(React);
var processingInstructions = [
{
//// subMenus \\// subMenus \\\\
replaceChildren: true,
shouldProcessNode: function (node) {
return node.attribs && node.attribs["data-cat"] === "submenu";
},
processNode: function (node, children) {
return (
<li className="menu-link">
{pageName[0]}
<NavBar children={children} />
</li>
);
},
},
{
// replaceChildren:true,
shouldProcessNode: function (node) {
return node.parent && node.parent.name && node.parent.name === "h1";
},
processNode: function (node, children) {
return null;
},
},
{
// Anything else
shouldProcessNode: function (node) {
return true;
},
processNode: processNodeDefinitions.processDefaultNode,
},
];
var processingInstructionsTwo = [
{
//// subMenus \\// subMenus \\\\
replaceChildren: true,
shouldProcessNode: function (node) {
return node.attribs && node.attribs["data-cat"] === "submenu";
},
processNode: function (node, children) {
return (
<li className="menu-link">
{pageName[1]}
<NavBar children={children} />
</li>
);
},
},
{
// replaceChildren:true,
shouldProcessNode: function (node) {
return node.parent && node.parent.name && node.parent.name === "h1";
},
processNode: function (node, children) {
return null;
},
},
{
// Anything else
shouldProcessNode: function (node) {
return true;
},
processNode: processNodeDefinitions.processDefaultNode,
},
];
var htmlToReactParser = new HtmlToReactParser();
var reactComponent = htmlToReactParser.parseWithInstructions(
htmlInput,
() => true,
processingInstructions
);
var reactComponenttwo = htmlToReactParser.parseWithInstructions(
htmlInputTwo,
() => true,
processingInstructionsTwo
);
return (
<div style={{ backgroundColor: "silver" }}>
<Container
style={{
maxWidth: "1060px",
width: "100%",
height: "auto",
display: "block",
}}
>
<Grid container alignItems="center" style={{ display: "flex" }}>
<Grid item xs={5}>
Logo
</Grid>
<Grid item xs={7}>
<nav>
<ul style={{ display: "flex" }}>
{reactComponent}
{reactComponenttwo}
</ul>
</nav>
</Grid>
</Grid>
</Container>
</div>
);
}
export default NavBarContent;
Any help would be much appreciated.
Upvotes: 0
Views: 52
Reputation: 874
Will suggest you to start creating a Builder
for the processing instructions. This will give you control over the order and properties you setup, but also to scale the builders to a library that allow you to encapsulate some boilerplate code in the future.
The code below is not intended as a complete solution, but as a sample of what could be done to address the problem of organizing and somewhat guarantee the order of instructions definitions.
Something along the lines of:
/*
* Setup the processing instructions builder
*/
function processingInstructionsBuilder() {
var _instructions = [];
}
processingInstructionsBuilder.prototype.end = function() {
return [...instructions];
};
processingInstructionsBuilder.prototype.newInstructions = function() {
var builder = new instructionsBuilder(this, (props) => {
this._instructions.push(props);
});
return builder;
};
// other builder functions here...
/*
* Setup the instructions builder
*/
function instructionsBuilder(parent, endCallback) {
var _parent = parent || null;
var _endCallback = endCallback || null;
var _properties = {};
}
instructionsBuilder.prototype.end = function() {
if (!!_endCallback) {
_endCallback(_properties);
}
return this._parent || this._properties;
};
instructionsBuilder.prototype.canReplaceChildren = function(trueOrFalse) {
// Some validations here...
this._properties.replaceChildren = trueOrFalse;
return this;
};
instructionsBuilder.prototype.shouldProcessNode = function(shouldProcessNodeFunc) {
// Some validations here...
this._properties.shouldProcessNode = shouldProcessNodeFunc;
return this;
};
instructionsBuilder.prototype.processNode = function(processNodeFunc) {
// Some validations here...
this._properties.processNode = processNodeFunc;
return this;
};
// other builder functions here...
Some sample usage...
/*
* Usage...
*/
var builder = new processingInstructionsBuilder();
// Gets an array with processing instructions, in the created order...
var instructions = builder
.newInstructions(/* instructions 1 */)
.canReplaceChildren(true)
.shouldProcessNode(function(node) {
// some useful code here...
})
.processNode(function (node, children) {
// some useful code here...
})
.end(/* instructions 1 */)
.newInstructions(/* instructions 2 */)
.canReplaceChildren(false)
.shouldProcessNode(function(node) {
// some useful code here...
})
.processNode(function (node, children) {
// some useful code here...
})
.end(/* instructions 2 */)
.end(/* processing instructions builder */);
/*
* Alternative usage...
*/
var builder1 = new instructionsBuilder();
var inst1 = builder1.canReplaceChildren(true)
.shouldProcessNode(function(node) {
// some useful code here...
})
.processNode(function (node, children) {
// some useful code here...
})
.end(/* instructions 1 */);
var builder2 = new instructionsBuilder();
var inst1 = builder2
.canReplaceChildren(false)
.shouldProcessNode(function(node) {
// some useful code here...
})
.processNode(function (node, children) {
// some useful code here...
})
.end(/* instructions 2 */);
Upvotes: 0