Thoughts on the implementation of recursive react.js navigation menu
$begingroup$
I'm very new to React.js and have to start converting an entire website at my work. It's fun, but I'm hoping to get some feedback about how I tackled building this navigation component as I don't fully understand best practices when it comes to structuring components as well as proper state and props management.
I have uploaded the full working example to me repo here if you want to clone and run locally: https://github.com/tayloraleach/recursive-react-material-ui-menu
Here are the two components I built that compose the navigation:
The main navigation component that holds all the children
MobileNavigation.jsx
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import MobileNavigationMenuItem from './MobileNavigationMenuItem';
import classnames from 'classnames';
import List from '@material-ui/core/List';
class MobileNavigation extends React.Component {
state = {
currentOpenChildId: null
};
handleCurrentlyOpen = (id) => {
this.setState({
currentOpenChildId: id
});
};
render() {
const { classes } = this.props;
// Loop through the navigation array and create a new component for each,
// passing the current menuItem and its children as props
const nodes = this.props.data.navigation.map((item) => {
return (
<MobileNavigationMenuItem
key={item.id}
node={item}
passToParent={this.handleCurrentlyOpen}
currentlyOpen={this.state.currentOpenChildId}>
{item.children}
</MobileNavigationMenuItem>
);
});
return (
<List disablePadding className={classnames([this.props.styles, classes.root])}>
{nodes}
</List>
);
}
}
MobileNavigation.propTypes = {
classes: PropTypes.object.isRequired,
styles: PropTypes.string,
data: PropTypes.object.isRequired
};
const styles = (theme) => ({
root: {
width: '100%',
padding: 0,
boxShadow: 'inset 0 1px 0 0 rgba(255, 255, 255, 0.15)',
background: "#222"
},
link: {
color: '#fff',
textDecoration: 'none'
}
});
export default withStyles(styles)(MobileNavigation);
And each item of the navigation that gets called recursively
MobileNavigationMenuItem.jsx
import React from 'react';
import { ListItem, Collapse, List } from '@material-ui/core';
import ArrowDropDown from '@material-ui/icons/ArrowDropDown';
import ArrowDropUp from '@material-ui/icons/ArrowDropUp';
import { withStyles } from '@material-ui/core/styles';
import classnames from 'classnames';
import PropTypes from 'prop-types';
class MobileNavigationMenuItem extends React.Component {
state = {
open: false,
id: this.props.node.id,
currentOpenChildId: null
};
handleClick = () => {
if (this.props.currentlyOpen == this.props.node.id) {
this.setState((state) => ({ open: !state.open }));
} else {
this.setState({ open: true }, this.props.passToParent(this.props.node.id));
}
};
handleCurrentlyOpen = (id) => {
this.setState({
currentOpenChildId: id
});
};
// These got separated due to having an inner div inside each item to be able to set a max width and maintain styles
getNestedBackgroundColor(depth) {
const styles = {
backgroundColor: 'rgba(255, 255, 255, 0.05)'
};
if (depth === 1) {
styles.backgroundColor = 'rgba(255, 255, 255, 0.1)';
}
if (depth === 2) {
styles.backgroundColor = 'rgba(255, 255, 255, 0.15)';
}
return styles;
}
getNestedPadding(depth) {
const styles = {
paddingLeft: 0
};
if (depth === 1) {
styles.paddingLeft = 15;
}
if (depth === 2) {
styles.paddingLeft = 30;
}
return styles;
}
render() {
const { classes } = this.props;
let childnodes = null;
// The MobileNavigationMenuItem component calls itself if there are children
// Need to pass classes as a prop or it falls out of scope
if (this.props.children) {
childnodes = this.props.children.map((childnode) => {
return (
<MobileNavigationMenuItem
key={childnode.id}
node={childnode}
classes={classes}
passToParent={this.handleCurrentlyOpen}
currentlyOpen={this.state.currentOpenChildId}>
{childnode.children}
</MobileNavigationMenuItem>
);
});
}
// Return a ListItem element
// Display children if there are any
return (
<React.Fragment>
<ListItem
onClick={this.handleClick}
className={classes.item}
style={this.getNestedBackgroundColor(this.props.node.depth)}>
<div className={classes.wrapper}>
<a
href=""
style={this.getNestedPadding(this.props.node.depth)}
className={classnames([classes.link, !childnodes.length && classes.goFullWidth])}>
{this.props.node.title}
</a>
{childnodes.length > 0 &&
(this.props.currentlyOpen == this.props.node.id && this.state.open ? (
<ArrowDropUp />
) : (
<ArrowDropDown />
))}
</div>
</ListItem>
{childnodes.length > 0 && (
<Collapse
in={this.props.currentlyOpen == this.props.node.id && this.state.open}
timeout="auto"
unmountOnExit>
<List disablePadding>{childnodes}</List>
</Collapse>
)}
</React.Fragment>
);
}
}
MobileNavigationMenuItem.propTypes = {
classes: PropTypes.object.isRequired,
node: PropTypes.object.isRequired,
children: PropTypes.array.isRequired,
passToParent: PropTypes.func.isRequired,
currentlyOpen: PropTypes.string
};
const styles = (theme) => ({
link: {
color: '#fff',
textDecoration: 'none'
},
goFullWidth: {
width: '100%'
},
item: {
minHeight: 48,
color: '#fff',
backgroundColor: 'rgba(255, 255, 255, 0.05)',
padding: '12px 15px',
boxShadow: 'inset 0 -1px 0 0 rgba(255, 255, 255, 0.15)',
'& svg': {
marginLeft: 'auto'
}
},
wrapper: {
width: '100%',
display: 'flex',
alignItems: 'center',
maxWidth: '440px', // any value here
margin: 'auto',
[theme.breakpoints.down('sm')]: {
maxWidth: '100%'
},
}
});
export default withStyles(styles)(MobileNavigationMenuItem);
I'll admit there is some code clean up I could do in regards to styling nested elements, but overall it works really well and I'm pretty proud of it.
The questions I have stemmed from how I'm closing and opening the children. Each menu item has an open state and acts as a 'parent' of any direct children. When you click an item, it passes the state up and if it the id matches it opens (closing all others).
Each item calls itself if it has children and repeats recursively.
I would love to get some insight on any improvements I can make or if this is a good or bad solution to the problem. Thanks!
javascript recursion react.js
New contributor
$endgroup$
add a comment |
$begingroup$
I'm very new to React.js and have to start converting an entire website at my work. It's fun, but I'm hoping to get some feedback about how I tackled building this navigation component as I don't fully understand best practices when it comes to structuring components as well as proper state and props management.
I have uploaded the full working example to me repo here if you want to clone and run locally: https://github.com/tayloraleach/recursive-react-material-ui-menu
Here are the two components I built that compose the navigation:
The main navigation component that holds all the children
MobileNavigation.jsx
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import MobileNavigationMenuItem from './MobileNavigationMenuItem';
import classnames from 'classnames';
import List from '@material-ui/core/List';
class MobileNavigation extends React.Component {
state = {
currentOpenChildId: null
};
handleCurrentlyOpen = (id) => {
this.setState({
currentOpenChildId: id
});
};
render() {
const { classes } = this.props;
// Loop through the navigation array and create a new component for each,
// passing the current menuItem and its children as props
const nodes = this.props.data.navigation.map((item) => {
return (
<MobileNavigationMenuItem
key={item.id}
node={item}
passToParent={this.handleCurrentlyOpen}
currentlyOpen={this.state.currentOpenChildId}>
{item.children}
</MobileNavigationMenuItem>
);
});
return (
<List disablePadding className={classnames([this.props.styles, classes.root])}>
{nodes}
</List>
);
}
}
MobileNavigation.propTypes = {
classes: PropTypes.object.isRequired,
styles: PropTypes.string,
data: PropTypes.object.isRequired
};
const styles = (theme) => ({
root: {
width: '100%',
padding: 0,
boxShadow: 'inset 0 1px 0 0 rgba(255, 255, 255, 0.15)',
background: "#222"
},
link: {
color: '#fff',
textDecoration: 'none'
}
});
export default withStyles(styles)(MobileNavigation);
And each item of the navigation that gets called recursively
MobileNavigationMenuItem.jsx
import React from 'react';
import { ListItem, Collapse, List } from '@material-ui/core';
import ArrowDropDown from '@material-ui/icons/ArrowDropDown';
import ArrowDropUp from '@material-ui/icons/ArrowDropUp';
import { withStyles } from '@material-ui/core/styles';
import classnames from 'classnames';
import PropTypes from 'prop-types';
class MobileNavigationMenuItem extends React.Component {
state = {
open: false,
id: this.props.node.id,
currentOpenChildId: null
};
handleClick = () => {
if (this.props.currentlyOpen == this.props.node.id) {
this.setState((state) => ({ open: !state.open }));
} else {
this.setState({ open: true }, this.props.passToParent(this.props.node.id));
}
};
handleCurrentlyOpen = (id) => {
this.setState({
currentOpenChildId: id
});
};
// These got separated due to having an inner div inside each item to be able to set a max width and maintain styles
getNestedBackgroundColor(depth) {
const styles = {
backgroundColor: 'rgba(255, 255, 255, 0.05)'
};
if (depth === 1) {
styles.backgroundColor = 'rgba(255, 255, 255, 0.1)';
}
if (depth === 2) {
styles.backgroundColor = 'rgba(255, 255, 255, 0.15)';
}
return styles;
}
getNestedPadding(depth) {
const styles = {
paddingLeft: 0
};
if (depth === 1) {
styles.paddingLeft = 15;
}
if (depth === 2) {
styles.paddingLeft = 30;
}
return styles;
}
render() {
const { classes } = this.props;
let childnodes = null;
// The MobileNavigationMenuItem component calls itself if there are children
// Need to pass classes as a prop or it falls out of scope
if (this.props.children) {
childnodes = this.props.children.map((childnode) => {
return (
<MobileNavigationMenuItem
key={childnode.id}
node={childnode}
classes={classes}
passToParent={this.handleCurrentlyOpen}
currentlyOpen={this.state.currentOpenChildId}>
{childnode.children}
</MobileNavigationMenuItem>
);
});
}
// Return a ListItem element
// Display children if there are any
return (
<React.Fragment>
<ListItem
onClick={this.handleClick}
className={classes.item}
style={this.getNestedBackgroundColor(this.props.node.depth)}>
<div className={classes.wrapper}>
<a
href=""
style={this.getNestedPadding(this.props.node.depth)}
className={classnames([classes.link, !childnodes.length && classes.goFullWidth])}>
{this.props.node.title}
</a>
{childnodes.length > 0 &&
(this.props.currentlyOpen == this.props.node.id && this.state.open ? (
<ArrowDropUp />
) : (
<ArrowDropDown />
))}
</div>
</ListItem>
{childnodes.length > 0 && (
<Collapse
in={this.props.currentlyOpen == this.props.node.id && this.state.open}
timeout="auto"
unmountOnExit>
<List disablePadding>{childnodes}</List>
</Collapse>
)}
</React.Fragment>
);
}
}
MobileNavigationMenuItem.propTypes = {
classes: PropTypes.object.isRequired,
node: PropTypes.object.isRequired,
children: PropTypes.array.isRequired,
passToParent: PropTypes.func.isRequired,
currentlyOpen: PropTypes.string
};
const styles = (theme) => ({
link: {
color: '#fff',
textDecoration: 'none'
},
goFullWidth: {
width: '100%'
},
item: {
minHeight: 48,
color: '#fff',
backgroundColor: 'rgba(255, 255, 255, 0.05)',
padding: '12px 15px',
boxShadow: 'inset 0 -1px 0 0 rgba(255, 255, 255, 0.15)',
'& svg': {
marginLeft: 'auto'
}
},
wrapper: {
width: '100%',
display: 'flex',
alignItems: 'center',
maxWidth: '440px', // any value here
margin: 'auto',
[theme.breakpoints.down('sm')]: {
maxWidth: '100%'
},
}
});
export default withStyles(styles)(MobileNavigationMenuItem);
I'll admit there is some code clean up I could do in regards to styling nested elements, but overall it works really well and I'm pretty proud of it.
The questions I have stemmed from how I'm closing and opening the children. Each menu item has an open state and acts as a 'parent' of any direct children. When you click an item, it passes the state up and if it the id matches it opens (closing all others).
Each item calls itself if it has children and repeats recursively.
I would love to get some insight on any improvements I can make or if this is a good or bad solution to the problem. Thanks!
javascript recursion react.js
New contributor
$endgroup$
add a comment |
$begingroup$
I'm very new to React.js and have to start converting an entire website at my work. It's fun, but I'm hoping to get some feedback about how I tackled building this navigation component as I don't fully understand best practices when it comes to structuring components as well as proper state and props management.
I have uploaded the full working example to me repo here if you want to clone and run locally: https://github.com/tayloraleach/recursive-react-material-ui-menu
Here are the two components I built that compose the navigation:
The main navigation component that holds all the children
MobileNavigation.jsx
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import MobileNavigationMenuItem from './MobileNavigationMenuItem';
import classnames from 'classnames';
import List from '@material-ui/core/List';
class MobileNavigation extends React.Component {
state = {
currentOpenChildId: null
};
handleCurrentlyOpen = (id) => {
this.setState({
currentOpenChildId: id
});
};
render() {
const { classes } = this.props;
// Loop through the navigation array and create a new component for each,
// passing the current menuItem and its children as props
const nodes = this.props.data.navigation.map((item) => {
return (
<MobileNavigationMenuItem
key={item.id}
node={item}
passToParent={this.handleCurrentlyOpen}
currentlyOpen={this.state.currentOpenChildId}>
{item.children}
</MobileNavigationMenuItem>
);
});
return (
<List disablePadding className={classnames([this.props.styles, classes.root])}>
{nodes}
</List>
);
}
}
MobileNavigation.propTypes = {
classes: PropTypes.object.isRequired,
styles: PropTypes.string,
data: PropTypes.object.isRequired
};
const styles = (theme) => ({
root: {
width: '100%',
padding: 0,
boxShadow: 'inset 0 1px 0 0 rgba(255, 255, 255, 0.15)',
background: "#222"
},
link: {
color: '#fff',
textDecoration: 'none'
}
});
export default withStyles(styles)(MobileNavigation);
And each item of the navigation that gets called recursively
MobileNavigationMenuItem.jsx
import React from 'react';
import { ListItem, Collapse, List } from '@material-ui/core';
import ArrowDropDown from '@material-ui/icons/ArrowDropDown';
import ArrowDropUp from '@material-ui/icons/ArrowDropUp';
import { withStyles } from '@material-ui/core/styles';
import classnames from 'classnames';
import PropTypes from 'prop-types';
class MobileNavigationMenuItem extends React.Component {
state = {
open: false,
id: this.props.node.id,
currentOpenChildId: null
};
handleClick = () => {
if (this.props.currentlyOpen == this.props.node.id) {
this.setState((state) => ({ open: !state.open }));
} else {
this.setState({ open: true }, this.props.passToParent(this.props.node.id));
}
};
handleCurrentlyOpen = (id) => {
this.setState({
currentOpenChildId: id
});
};
// These got separated due to having an inner div inside each item to be able to set a max width and maintain styles
getNestedBackgroundColor(depth) {
const styles = {
backgroundColor: 'rgba(255, 255, 255, 0.05)'
};
if (depth === 1) {
styles.backgroundColor = 'rgba(255, 255, 255, 0.1)';
}
if (depth === 2) {
styles.backgroundColor = 'rgba(255, 255, 255, 0.15)';
}
return styles;
}
getNestedPadding(depth) {
const styles = {
paddingLeft: 0
};
if (depth === 1) {
styles.paddingLeft = 15;
}
if (depth === 2) {
styles.paddingLeft = 30;
}
return styles;
}
render() {
const { classes } = this.props;
let childnodes = null;
// The MobileNavigationMenuItem component calls itself if there are children
// Need to pass classes as a prop or it falls out of scope
if (this.props.children) {
childnodes = this.props.children.map((childnode) => {
return (
<MobileNavigationMenuItem
key={childnode.id}
node={childnode}
classes={classes}
passToParent={this.handleCurrentlyOpen}
currentlyOpen={this.state.currentOpenChildId}>
{childnode.children}
</MobileNavigationMenuItem>
);
});
}
// Return a ListItem element
// Display children if there are any
return (
<React.Fragment>
<ListItem
onClick={this.handleClick}
className={classes.item}
style={this.getNestedBackgroundColor(this.props.node.depth)}>
<div className={classes.wrapper}>
<a
href=""
style={this.getNestedPadding(this.props.node.depth)}
className={classnames([classes.link, !childnodes.length && classes.goFullWidth])}>
{this.props.node.title}
</a>
{childnodes.length > 0 &&
(this.props.currentlyOpen == this.props.node.id && this.state.open ? (
<ArrowDropUp />
) : (
<ArrowDropDown />
))}
</div>
</ListItem>
{childnodes.length > 0 && (
<Collapse
in={this.props.currentlyOpen == this.props.node.id && this.state.open}
timeout="auto"
unmountOnExit>
<List disablePadding>{childnodes}</List>
</Collapse>
)}
</React.Fragment>
);
}
}
MobileNavigationMenuItem.propTypes = {
classes: PropTypes.object.isRequired,
node: PropTypes.object.isRequired,
children: PropTypes.array.isRequired,
passToParent: PropTypes.func.isRequired,
currentlyOpen: PropTypes.string
};
const styles = (theme) => ({
link: {
color: '#fff',
textDecoration: 'none'
},
goFullWidth: {
width: '100%'
},
item: {
minHeight: 48,
color: '#fff',
backgroundColor: 'rgba(255, 255, 255, 0.05)',
padding: '12px 15px',
boxShadow: 'inset 0 -1px 0 0 rgba(255, 255, 255, 0.15)',
'& svg': {
marginLeft: 'auto'
}
},
wrapper: {
width: '100%',
display: 'flex',
alignItems: 'center',
maxWidth: '440px', // any value here
margin: 'auto',
[theme.breakpoints.down('sm')]: {
maxWidth: '100%'
},
}
});
export default withStyles(styles)(MobileNavigationMenuItem);
I'll admit there is some code clean up I could do in regards to styling nested elements, but overall it works really well and I'm pretty proud of it.
The questions I have stemmed from how I'm closing and opening the children. Each menu item has an open state and acts as a 'parent' of any direct children. When you click an item, it passes the state up and if it the id matches it opens (closing all others).
Each item calls itself if it has children and repeats recursively.
I would love to get some insight on any improvements I can make or if this is a good or bad solution to the problem. Thanks!
javascript recursion react.js
New contributor
$endgroup$
I'm very new to React.js and have to start converting an entire website at my work. It's fun, but I'm hoping to get some feedback about how I tackled building this navigation component as I don't fully understand best practices when it comes to structuring components as well as proper state and props management.
I have uploaded the full working example to me repo here if you want to clone and run locally: https://github.com/tayloraleach/recursive-react-material-ui-menu
Here are the two components I built that compose the navigation:
The main navigation component that holds all the children
MobileNavigation.jsx
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import MobileNavigationMenuItem from './MobileNavigationMenuItem';
import classnames from 'classnames';
import List from '@material-ui/core/List';
class MobileNavigation extends React.Component {
state = {
currentOpenChildId: null
};
handleCurrentlyOpen = (id) => {
this.setState({
currentOpenChildId: id
});
};
render() {
const { classes } = this.props;
// Loop through the navigation array and create a new component for each,
// passing the current menuItem and its children as props
const nodes = this.props.data.navigation.map((item) => {
return (
<MobileNavigationMenuItem
key={item.id}
node={item}
passToParent={this.handleCurrentlyOpen}
currentlyOpen={this.state.currentOpenChildId}>
{item.children}
</MobileNavigationMenuItem>
);
});
return (
<List disablePadding className={classnames([this.props.styles, classes.root])}>
{nodes}
</List>
);
}
}
MobileNavigation.propTypes = {
classes: PropTypes.object.isRequired,
styles: PropTypes.string,
data: PropTypes.object.isRequired
};
const styles = (theme) => ({
root: {
width: '100%',
padding: 0,
boxShadow: 'inset 0 1px 0 0 rgba(255, 255, 255, 0.15)',
background: "#222"
},
link: {
color: '#fff',
textDecoration: 'none'
}
});
export default withStyles(styles)(MobileNavigation);
And each item of the navigation that gets called recursively
MobileNavigationMenuItem.jsx
import React from 'react';
import { ListItem, Collapse, List } from '@material-ui/core';
import ArrowDropDown from '@material-ui/icons/ArrowDropDown';
import ArrowDropUp from '@material-ui/icons/ArrowDropUp';
import { withStyles } from '@material-ui/core/styles';
import classnames from 'classnames';
import PropTypes from 'prop-types';
class MobileNavigationMenuItem extends React.Component {
state = {
open: false,
id: this.props.node.id,
currentOpenChildId: null
};
handleClick = () => {
if (this.props.currentlyOpen == this.props.node.id) {
this.setState((state) => ({ open: !state.open }));
} else {
this.setState({ open: true }, this.props.passToParent(this.props.node.id));
}
};
handleCurrentlyOpen = (id) => {
this.setState({
currentOpenChildId: id
});
};
// These got separated due to having an inner div inside each item to be able to set a max width and maintain styles
getNestedBackgroundColor(depth) {
const styles = {
backgroundColor: 'rgba(255, 255, 255, 0.05)'
};
if (depth === 1) {
styles.backgroundColor = 'rgba(255, 255, 255, 0.1)';
}
if (depth === 2) {
styles.backgroundColor = 'rgba(255, 255, 255, 0.15)';
}
return styles;
}
getNestedPadding(depth) {
const styles = {
paddingLeft: 0
};
if (depth === 1) {
styles.paddingLeft = 15;
}
if (depth === 2) {
styles.paddingLeft = 30;
}
return styles;
}
render() {
const { classes } = this.props;
let childnodes = null;
// The MobileNavigationMenuItem component calls itself if there are children
// Need to pass classes as a prop or it falls out of scope
if (this.props.children) {
childnodes = this.props.children.map((childnode) => {
return (
<MobileNavigationMenuItem
key={childnode.id}
node={childnode}
classes={classes}
passToParent={this.handleCurrentlyOpen}
currentlyOpen={this.state.currentOpenChildId}>
{childnode.children}
</MobileNavigationMenuItem>
);
});
}
// Return a ListItem element
// Display children if there are any
return (
<React.Fragment>
<ListItem
onClick={this.handleClick}
className={classes.item}
style={this.getNestedBackgroundColor(this.props.node.depth)}>
<div className={classes.wrapper}>
<a
href=""
style={this.getNestedPadding(this.props.node.depth)}
className={classnames([classes.link, !childnodes.length && classes.goFullWidth])}>
{this.props.node.title}
</a>
{childnodes.length > 0 &&
(this.props.currentlyOpen == this.props.node.id && this.state.open ? (
<ArrowDropUp />
) : (
<ArrowDropDown />
))}
</div>
</ListItem>
{childnodes.length > 0 && (
<Collapse
in={this.props.currentlyOpen == this.props.node.id && this.state.open}
timeout="auto"
unmountOnExit>
<List disablePadding>{childnodes}</List>
</Collapse>
)}
</React.Fragment>
);
}
}
MobileNavigationMenuItem.propTypes = {
classes: PropTypes.object.isRequired,
node: PropTypes.object.isRequired,
children: PropTypes.array.isRequired,
passToParent: PropTypes.func.isRequired,
currentlyOpen: PropTypes.string
};
const styles = (theme) => ({
link: {
color: '#fff',
textDecoration: 'none'
},
goFullWidth: {
width: '100%'
},
item: {
minHeight: 48,
color: '#fff',
backgroundColor: 'rgba(255, 255, 255, 0.05)',
padding: '12px 15px',
boxShadow: 'inset 0 -1px 0 0 rgba(255, 255, 255, 0.15)',
'& svg': {
marginLeft: 'auto'
}
},
wrapper: {
width: '100%',
display: 'flex',
alignItems: 'center',
maxWidth: '440px', // any value here
margin: 'auto',
[theme.breakpoints.down('sm')]: {
maxWidth: '100%'
},
}
});
export default withStyles(styles)(MobileNavigationMenuItem);
I'll admit there is some code clean up I could do in regards to styling nested elements, but overall it works really well and I'm pretty proud of it.
The questions I have stemmed from how I'm closing and opening the children. Each menu item has an open state and acts as a 'parent' of any direct children. When you click an item, it passes the state up and if it the id matches it opens (closing all others).
Each item calls itself if it has children and repeats recursively.
I would love to get some insight on any improvements I can make or if this is a good or bad solution to the problem. Thanks!
javascript recursion react.js
javascript recursion react.js
New contributor
New contributor
New contributor
asked 6 mins ago
Taylor A. LeachTaylor A. Leach
1011
1011
New contributor
New contributor
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Taylor A. Leach is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212733%2fthoughts-on-the-implementation-of-recursive-react-js-navigation-menu%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Taylor A. Leach is a new contributor. Be nice, and check out our Code of Conduct.
Taylor A. Leach is a new contributor. Be nice, and check out our Code of Conduct.
Taylor A. Leach is a new contributor. Be nice, and check out our Code of Conduct.
Taylor A. Leach is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212733%2fthoughts-on-the-implementation-of-recursive-react-js-navigation-menu%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown