React .map не является функцией для массива объектов

Я пытаюсь получить все продукты из моего API.
Код API для продуктов приведен ниже.
Код ниже работает хорошо:

const heh = () => {
        products.map((p) => console.info(p.id))
    }

Проблема в том, что products.map в моем const allProducts говорит мне TypeError: products.map is not a function.
P.S. Я проверил все типы. Я получаю массив объектов. Полный код ниже:

const Product = ({products}) => {
    const heh = () => {
        products.map((p) => console.info(p.id))
    }
    const allProducts = products.map((p) => (
        <div className = "product" key = {p.id}>
            <h3>{p.name} - {p.price}</h3>
            <p>{p.description}</p>
        </div>)
        )
    return (
        <div>
            <button onClick = {() => heh()}>Click</button>
            {allProducts}
        </div>
        
    )
}


const Test = () => {
    const [products, setProducts] = React.useState([])

    React.useEffect(() => {
        const fetchProducts = async () => {
            const result = await axios('/api/v1/products')
            console.info(result.data.data)
            setProducts(result.data)
        }

        fetchProducts()
        
    }, [])

    return (
        <div>
            <Product products = {products} />
        </div>
    )
}

ReactDOM.render(React.createElement(Test), document.getElementById('app'))

ТС:

const result = await client.query("SELECT * FROM products")
        const products = new Array()

        result.rows.map(p => {
            let obj: any = new Object()
            result.rowDescription.columns.map((el, i) => {
                obj[el.name] = p[i]
            })

            products.push(obj)
        })

        response.body = {
            success: true,
            data: products
        }

Вы уверены, что проверили типы в нужное время? Я бы предложил либо установить точку останова отладчика на строке const allProducts = products.map((p) => ( и проверить значение products, когда программа останавливается там, либо добавить console.info("products:", products) непосредственно перед этой строкой.

Ilmari Karonen 26.12.2020 18:34
React.useState(0), начните с числа, вы ожидаете, что это будет массив. Что? Я имею в виду, что useEffect делает что-то после рендеринга, ваш fetch асинхронный, это две причины, по которым ваше значение по умолчанию имеет значение?
ASDFGerte 26.12.2020 18:35

в своем тесте вы делаете console.info(result.data.data), но затем вы передаете result.data функции setProducts. Вы уверены, что нет вложенной переменной с именем data, где внутренняя data — это массив продуктов.

masoodahm 26.12.2020 18:38

продукты инициализируются числом (0), тогда вы назначаете массив, поэтому он должен быть const [products, setProducts] = React.useState([])

Lashan Fernando 26.12.2020 18:44
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
1 397
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

почему бы вам вместо этого не попробовать это:

return (
        <div>
            <button onClick = {() => heh()}>Click</button>
            {products.map((p) => (
        return (<div className = "product" key = {p.id}>
            <h3>{p.name} - {p.price}</h3>
            <p>{p.description}</p>
        </div>))}
        </div>
        
    )

та же проблема. Я знал об этом, и это был мой первый вариант :(

Morani 26.12.2020 18:37

как предложено другими, сделайте это const [products, setProducts] = React.useState([])

Sakshi 26.12.2020 18:38

вы делаете console.info result.data.data, но храните внутри продукты result.data, может ли это вызвать проблему?

Sakshi 26.12.2020 18:53
Ответ принят как подходящий

Ваше начальное состояние для products0. Это означает, что когда вы передадите его в Product в первый раз, это будет число, а не массив. У чисел нет функции map, поэтому вы получите сообщение об ошибке.

Если products будет массивом, используйте [] в качестве его начального состояния:

const [products, setProducts] = React.useState([])
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^

...или значение флага, например null, которое вы проверяете перед попыткой использовать map.


Примечание: вы неправильно используете map. Если вы не возвращаете значение из обратного вызова map и не используете новый массив, который создает map, вам не следует использовать map. Используйте forEach или простой цикл.

Ага. Ты был прав. Что-то происходит с моим приложением по некоторым причинам. Спасибо.

Morani 26.12.2020 18:57

Когда ваша функция heh выполняется, список продуктов загружается и представляет собой массив.

Вы получили ошибку в строке const allProducts = ..., потому что вы установили значение продуктов по умолчанию в виде числа. В этой строке

const [products, setProducts] = React.useState(0)

Замените пустым массивом по умолчанию, чтобы решить вашу проблему:

const [products, setProducts] = React.useState([])

Вы получаете ошибку, потому что вы инициализируете состояние свойства продуктов значением 0, которое не является итерируемым объектом. Инициализируйте его с помощью useState([]).

Когда вы вводили заголовок вопроса, вы должны были сразу определить свою проблему -

React .map не является функцией для массива объектов

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

нет!!! кто научил тебя так писать код? вы используете .map неправильно двумя способами: 1) как .forEach и 2) как .reduce. Более правильное использование response.body = { success: true, products: results.rows.map(row => result.rowDescription.columns.reduce((r, col, i) => Object.assign(r, { [col.name]: row[i] }), {}))

Mulan 26.12.2020 18:54

Другие вопросы по теме