问题
I am building a page with a horizontal menu of categories and subcategories to be populated with database data using react and react-bootstrap.
The database table (namely levels
) has the following structure:
id | level_name | category | subcategory | parent_id
If the row is for a category
then subcategory
and parent_id
have the value 0
and category
contains 1
. If the row is for a subcategory then category
column contains 0
, subcategory
contains 1
and parent_id
has the id
of the category of which this is a subcategory.
While building the horizontal menu of categories with subcategories as drop down items , I iterate over the database table and when I get a row with zero as the value in parent_id
, I pick the id
value and iterate over the table again to find the subcategories.
To make things simple, you can just concentrate on the map
function used twice. That is where the problem occurs.
My reactJS code is :
class Header extends Component {
constructor (props) {
super(props)
this.state = {
levels_all:[],
cat_id_found:0,
cat_name:''
}
}
componentDidMount(prevProps) {
//levels_all gets the value through an ajax call with axios here
this.setState({
levels_all: levels_all
})
}// end of componentDidMount
render () {
var cat_id_found=0;
var cat_name = '';
return (
<>
<nav className='navbar navbar-expand-md navbar-light navbar-laravel'>
<div className='container'>
<Link className='navbar-brand' to='/'>Tasksman</Link>
</div>
</nav>
<Navbar bg="light" expand="lg">
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link href="#home">Home</Nav.Link>
<Nav.Link href="#link">Link</Nav.Link>
{
this.state.levels_all.map( (item, idx) => ( item.parent_id == 0 ?
(
cat_id_found=item.id,
cat_name = item.level_name
<NavDropdown title="Dropdown1111" id="basic-nav-dropdown">
this.state.levels_all.map( (item1, idx) =>
(
cat_id_found == item1.id ? (
<NavDropdown.Item href="#action/3.1">item1.level_name</NavDropdown.Item>
):(
)
))
</NavDropdown>
) : (
)
))
}
</Nav>
</Navbar.Collapse>
</Navbar>
<h1>THIS IS HEADER </h1>
</>
)
}
}
export default Header
But I get the following error in command prompt while running the command npm run watch
:
Header.js: Unexpected token, expected "," which indicates at the title
of the line -
<NavDropdown title="Dropdown1111" id="basic-nav-dropdown">.
Screenshot is here :
How to get rid of the error ?
EDIT:
I have ComponentDidMount
like this :
componentDidMount(prevProps) {
axios
.post('/api/fetchLevels')
.then(response => {
// redirect to the homepage
//history.push('/')
console.log("header response = ");
console.log(response);
var levels_all = response.data.result;
this.setState({
levels_all: levels_all
})
})
.catch(error => {
this.setState({
// errors: error.response.data.errors
errors: error
})
})
}// end of ComponentDidMount
回答1:
You get that error because you are re-assigning values in your ternary operator. To fix this you can switch to an if-else statement like this:
{
this.state.levels_all.map((item, idx) => {
if (item.parent_id == 0){
cat_id_found=item.id
cat_name = item.level_name
return (
<NavDropdown title="Dropdown1111" id="basic-nav-dropdown">
{
this.state.levels_all.map((item1, idx) => (
cat_id_found == item1.id ? (
<NavDropdown.Item href="#action/3.1">
{item1.level_name}
</NavDropdown.Item>
) : null))
}
</NavDropdown>
)
}
return null
})
}
Furthermore, I think it's better to use an if-else statement here because you are not returning anything in the else part so there's no point in using something so overkill and confusing.
来源:https://stackoverflow.com/questions/64359611/reactjs-building-a-dynamic-horizontal-menu-with-dropdown-items-in-react-bootstr