I've got this error:
TypeError: categories.map is not a function
This is App.js
:
export default function Header() {
const [categories, setCategories] = useState([]);
useEffect(() => {
const loadCategories = async () => {
let res = await API.get(endpoints['categories'])
setCategories(res.data)
}
loadCategories()
}, []);
return (
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand href="#home">ECoursesAPP</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Link className="nav-link" to="/">Trang chủ</Link>
{categories.map(c => <Link className="nav-link" to="#link">{c.name}</Link>)}
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
)
}
This is API.js
:
import axios from "axios";
export let endpoints = {
"categories": "/categories/"
}
export default axios.create({
baseURL: "http://localhost:8000"
})
CodePudding user response:
You should always have a null check before .map to avoid run-time errors
{(categories || []).map(c => <Link className="nav-link" to="#link">{c.name}</Link>)}
CodePudding user response:
probably your api end point does not return an array so you can fix that or you can use categories?.map
CodePudding user response:
At the first render, your categories
array is an empty array. So you are doing something like this:
[].map(item => <p>{item.name}</p>)
when there is no item in the array, using dot notation to get the item value will cause an issue.
There are two options for you:
- add a default value at initializing phase on
setState
, for example:
const [categories, setCategories] = useState([
{id: 0, name: "" , ...}
]);
- wait for the API response before rendering the
categories
:
{
categories.length > 0 && categories.map(
// rest of the codes ...
)
}
Update
there is another issue with your api.js
In Javascript objects, no need to wrap the key
with the quotation marks. so remove it from categories
:
let endpoints = {
categories : "/categories/"
}
CodePudding user response:
Hey According to your error the issue is array not show element at first time rendering so you use the logic if array exist then array map the data let i show you
export default function Header() {
const [categories, setCategories] = useState([]);
useEffect(() => {
const loadCategories = async () => {
let res = await API.get(endpoints['categories'])
setCategories(res.data)
}
loadCategories()
}, []);
return (
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand href="#home">ECoursesAPP</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Link className="nav-link" to="/">Trang chủ</Link>
{categories && categories.map(c => <Link className="nav-link" to="#link">{c.name}</Link>)}
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
)
}