TypeError: categories.map не является функцией в ReactJs

Как исправить TypeError: categories.map не является функцией

    '''
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>
            )
        }

''' Это API.js: ''' import axios from "axios"; export let endpoints = { "categories": "/categories/" } export default axios.create({ baseURL: "http://localhost:8000" }) '''

Вы всегда должны иметь проверку на нуль перед .map, чтобы избежать ошибок во время выполнения

{(categories || []).map(c => <Link className="nav-link" to="#link">{c.name}</Link>)}

При первом рендере ваш массив categories является пустым массивом. Поэтому вы делаете что-то вроде этого:

[].map(item => <p>{item.name}</p>)

когда в массиве нет элемента, использование точечной нотации для получения значения элемента вызовет проблему.

Для вас есть два варианта:

  1. добавить значение по умолчанию на этапе инициализации на setState, например:
const [categories, setCategories] = useState([
  {id: 0, name: "" , ...}
]);
  1. дождитесь ответа API, прежде чем выводить categories:
{
  categories.length > 0 && categories.map(
    // rest of the codes ...
  )
}

Update

есть еще одна проблема с вашим api.js

В объектах Javascript нет необходимости заключать key в кавычки. поэтому удалите его из categories:

let endpoints = {
    categories : "/categories/"
}

Возможно, ваша конечная точка api не возвращает массив, поэтому вы можете исправить это или использовать категории?.map

Здравствуйте Согласно вашей ошибке проблема в том, что массив не показывает элемент при первом рендеринге, поэтому вы используете логику, если массив существует, то массив отображает данные, давайте я покажу вам

    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>
)

}

Вернуться на верх