Почему полезная нагрузка запроса пуста при использовании useState для установки в React?

У меня есть асинхронная функция внутри useEffect для извлечения данных на основе заданного ввода из базы данных (mongodb) с использованием Express.js. При отправке формы она должна передать состояние (введенные данные) на сервер и найти данные, а затем вернуть результат обратно в интерфейс. Но при отправке отправить пустое состояние и вернуть пустой массив.

ОтветЗапрос

Компонент реакции:Compare.js `

import React, { useState, useCallback } from "react";
import { useEffect } from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Result from "./Result";

export default function () {
  const [compare, setCompare] = useState({
    proId1: "",
    proId2: "",
  });

  function handleChangeEvent(event) {
    const { value, name } = event.target;
    setCompare((prevData) => ({
      ...prevData,
      [name]: value,
    }));
  }



  const fetchData = useCallback(async () => {
    const response = await fetch("http://localhost:3000/api/compare", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        proId1: compare.proId1,
        proId2: compare.proId2,
      }),
    });

    const data = await response.json();
    return data
  }, []);

  return (
    <>
      <div>
        <h1>ENTER IDS TO COMPARE</h1>
        <form>
          <input
            type = "text"
            className = "proId1"
            placeholder = "proId1"
            name = "proId1"
            onChange = {handleChangeEvent}
            value = {compare.proId1}
          />
          <input
            type = "text"
            className = "proId2"
            placeholder = "proId2"
            name = "proId2"
            onChange = {handleChangeEvent}
            value = {compare.proId2}
          />

          <button
            className = "submit"
            onClick = {
              React.useEffect(() => {
                fetchData()
              },[fetchData])
            }
          >
            SUBMIT
          </button>
        </form>
      </div>
      <Result />
    </>
  );
}

` сервер:

`

app.post("/api/compare", async  (req, res) => {
  try {
     let id1 = await req.body.proId1;
    let id2 = await req.body.proId2;
    let result = await model.find({ id: { $in: [id1, id2] } })
    res.send(result)
  } catch (error) {
    res.json({ status: "error", error: "error" });
  }
});

` ожидаемый запрос:

`

{
    "proId1":"1",
    "proId2":"3"

}

expected Response

[
    {
        "_id": "637c5dddb9b084433f13d3f7",
        "id": "1",
        "name": "dffdf",
        "price": "100$",
        "ratings": "2",
        "__v": 0
    },
    {
        "_id": "637c5df3b9b084433f13d3fb",
        "id": "3",
        "name": "dffdf",
        "price": "25$",
        "ratings": "5",
        "__v": 0
    }
]

`

Вы проверили, что состояние установлено правильно, перед запуском запроса?

Geshode 23.11.2022 10:01

да, я устанавливаю состояние «сравнить» всякий раз, когда значение в поле ввода изменяется.

Bilal 23.11.2022 10:06

Итак, если вы console.info(compare.proId1, compare.proId2) внутри useCallback перед const response, он показывает правильные значения?

Geshode 23.11.2022 10:10

НЕТ, он также пуст. Почему не устанавливается «сравнить»?

Bilal 23.11.2022 10:17

Чувак, быстрое исправление => onClick = { fetchData }, массив зависимостей useCallback [compare.proId1, compare.proId2], проверьте новые документы React beta.reactjs.org/learn/synchronizing-with-effects, в целом поможет , ваше здоровье

Azzy 23.11.2022 10:35
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
256
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ты неправильно используешь хуки.

Рекомендую внимательно прочитать эту статью и обратить внимание на useCallback и useEffect.

            onClick = {
              React.useEffect(() => {
                fetchData()
              },[fetchData])
            }

это не способ использования useEffect.

onClick вы хотите загрузить свои данные, так что сделайте

onClick = {fetchData}

Кроме того, useCallback без зависимостей также является бесшовным, это хук для запоминания, который содержит значения дохода, чтобы избежать подпрыгивания. Таким образом, вы можете поместить свое состояние в его зависимость, но мне это кажется немного чрезмерным, и вы можете использовать его без обёртки useCallback.

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

  const [apiResponse, setApiResponse] = useState();

  const fetchData = useCallback(async () => {
    const response = await fetch("http://localhost:3000/api/compare", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        proId1: compare.proId1,
        proId2: compare.proId2,
      }),
    });

    const data = await response.json();
    setApiResponse(data)
  }, [compare]);

и поместите куда-нибудь в свой возврат рендеринга

apiResponse.map(({ id, name }) => (<div key = {id}>{name}</div>))

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

Bilal 23.11.2022 11:02

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

Alex Shtromberg 23.11.2022 11:12

я хочу отобразить «apiResponse» в дочернем компоненте. Я попытался передать «apiResponse» в качестве опоры в дочерний элемент и консоль оттуда, но он показывает (на консоли) пустой массив

Bilal 23.11.2022 11:22

Спасибо, братан... я понял. Передача "события" в асинхронную функцию, а затем использование event.preventDefault() исправит проблему с исчезновением консоли... большое спасибо за вашу помощь, так как я новичок в кодирование и реакция

Bilal 23.11.2022 12:03

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