получение api происходит до того, как я отправлю форму

#javascript #reactjs

Вопрос:

Я использую react js в качестве фреймворка, а laravel-в качестве бэкэнд-фреймворка. Я также использую прокси. У меня есть функция, которую ханлде отправляет в моей форме. Каждый раз, когда я загружаю страницу формы, я получаю два ответа на своей консоли, хотя я еще не нажал кнопку «Отправить». Это мой компонент, созданный Аера. Я использую функциональный компонент

 import React, { useEffect, useState} from 'react';

const CreateDaerah = () => {
    const [nama, setNama] = useState('');

    const handleSubmit = (url = '', data = {}) => {
        fetch(url, {
            method: "POST",
            body: JSON.stringify(data),
            headers: {
                'Content-Type': 'application/json'
            }
        })
        .then(response => console.log(response))
        .catch(err => console.error(err));;
    }
    

    return(
        <div className="card-create">
            <form onSubmit={handleSubmit(`/api/provinsi`, nama)}>
                <h1>Form Provinsi</h1>
                <label htmlFor="nama">Nama</label>
                <input type="text" 
                        className="nama-provinsi" 
                        name="nama" 
                        placeholder="masukkan nama"
                />
                <button type="submit">Submit</button>
            </form>
        </div>
    );
}
 

Кроме того, как я могу получить значение nama из входных данных? Должен ли я использовать атрибут onChange?

Комментарии:

1. какой ответ вы получаете в консоли

2. Вы немедленно вызываете handleSubmit , а не передаете ссылку на функцию слушателю. onSubmit={() => handleSubmit('/api/provinsi', nama)} .

3. @AtalShrivastava Я получил ответ {тип: ‘базовый’, url: ‘ локальный хост:3000/добавить ‘, перенаправлено: верно, статус: 200, ок: верно, …}

4. onSubmit принимает функцию обратного вызова; @Andy абсолютно прав.

5. @Энди, а, понятно. Спасибо

Ответ №1:

Это связано с тем, что вы вызываете handleSubmit сразу при каждом рендеринге, а не предоставляете функцию для вызова при отправке. Вместо этого вы должны обновить его до чего-то вроде:

 import React, { useEffect, useState} from 'react';

const CreateDaerah = () => {
    const [nama, setNama] = useState('');

    const handleSubmit = (url = '', data = {}) => {
        fetch(url, {
            method: "POST",
            body: JSON.stringify(data),
            headers: {
                'Content-Type': 'application/json'
            }
        })
        .then(response => console.log(response))
        .catch(err => console.error(err));;
    }
    

    return(
        <div className="card-create">
            <form onSubmit={() => handleSubmit(`/api/provinsi`, nama)}>
                <h1>Form Provinsi</h1>
                <label htmlFor="nama">Nama</label>
                <input type="text" 
                        className="nama-provinsi" 
                        name="nama" 
                        placeholder="masukkan nama"
                />
                <button type="submit">Submit</button>
            </form>
        </div>
    );
}
 

Ответ №2:

  1. Вы вызываете handleSubmit функцию сразу после рендеринга, поэтому вам нужно либо передать ссылку на функцию вместо этого с обратным вызовом, либо просто передать ссылку на функцию без этих аргументов.
  2. Я, вероятно, не стал бы передавать эти аргументы. Я бы даже не стал использовать form элемент, так как элементы не нужно в него заворачивать. Я бы объявил URL-адрес в компоненте и поместил handleSubmit его на кнопку. Таким образом, вам не придется иметь дело с формой, обновляющей страницу.
  3. Поместите onChange обработчик на свой ввод, который вызывает функцию, обновляющую состояние, и пусть значение этого ввода будет результатом состояния.

Вот более короткий рабочий пример.

 const { useState } = React;

function Example() {

  const [ numa, setNuma ] = useState('');

  const url = `/api/provinsi`;

  function handleInput(e) {
    setNuma(e.target.value);
  }

  function handleClick() {
    console.log('Button clicked');
    console.log(`Final state: ${numa}`);
    // fetch(url) using numa state
  }

  return (
    <div>
      <input value={numa} onChange={handleInput} />
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

// Render it
ReactDOM.render(
  <Example />,
  document.getElementById("react")
); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div> 

Комментарии:

1. как я могу получить значение имени из входных данных? Должен ли я использовать атрибут onChange?

2. @YustinaYasin Я обновил свой ответ, чтобы он был немного более ясным. Я в основном удалил элемент формы, потому что у вас его нет, и вместо этого добавил кнопку отправить. У входных данных есть свой собственный обработчик, который обновляет состояние.

3. Я пробовал ваше решение, но оно не обновляет базу данных

4. Вам следует задать еще один вопрос об этом, включая ваш серверный код, так как это немного выходит за рамки компетенции этого вопроса. numa будет строкой, поэтому вам просто нужно body: numa , и она должна работать на основе представленного вами кода, если только API не ожидает чего-то другого, например объекта.

5. вы правы. Я должен отправить объект, а не строку. Огромное спасибо. Теперь это решено