Как мне заполнить поля формы в react из моего состояния?

#reactjs #react-hooks

Вопрос:

У меня есть форма редактирования, которая работает, за исключением того, что я не могу понять, как предварительно заполнить поля, чтобы при переходе к ней в соответствии с ее параметрами пользователь мог видеть текущее значение каждого поля, прежде чем переопределять его?

P.S. Это может выглядеть как дубликат моего другого поста, но это отдельная проблема

 import React from 'react'
import {useState, useEffect} from 'react'
import { Link } from 'react-router-dom'
import { useParams } from "react-router";

const EditTask = () => {
  const api ="http://localhost:5000"

  const [tasks, setTasks] = useState([]) 
  const [task, setTask] = useState([]) 
  const [text, setText] = useState('')
  const [day, setDay] = useState('')
  const [reminder, setReminder] = useState(false)
  const params  = useParams();

  const fetchTask = async () => {
    const res = await fetch(`${api}/tasks/${params.id}`, {
      method: "GET"
    })
    const data = await res.json()
    return data
  }

  //Get Request
  useEffect(() => {
    const getTask = async () => {
      const tasksFromServer = await fetchTask()
      setTask(tasksFromServer)
      console.log("tasksFromServer", tasksFromServer);
    }
    getTask()
  },[])


  //Update request
  const updateData = async (e) => {
    e.preventDefault()
    await fetchTask(task.id)
    const updateTask = {
      ...task, 
      reminder: reminder,
      text: text,
      day: day
    }
    console.log("updateTask", updateTask)

    await fetch(`${api}/tasks/${task.id}`, {
      method: 'PUT',
      headers: {
        'Content-type': 'application/json'
      },
      body: JSON.stringify(updateTask)          
    })

    setTasks(
      tasks.map((task) => 
        task.id === params.id 
        ? {...task, updateTask}
        : task
      )
    )
  }

  return (
    <div>
      <header className='header'>
        <h1>Edit</h1>
        <Link to="/" className="btn btn-primary">Go Back</Link>
      </header>
      <form className="add-form" onSubmit={updateData}>            
        <div className="form-control">
          <label>Task</label>
          <input type="text" placeholder="Add Task" value={text} onChange={(e)=> setText(e.target.value)} />
        </div>
        <div className="form-control">
          <label>Day amp; Time</label>
          <input type="text" placeholder="Add Day amp; Time"  value={day} onChange={(e)=> setDay(e.target.value)}/>
        </div>
        <div className="form-control form-control-check">
          <label>Set Reminder</label>
          <input type="checkbox" checked={reminder} value={reminder} onChange={(e)=> setReminder(e.currentTarget.checked)}/>
        </div>
        <input className="btn btn-block" type="submit" value="Save Task" />
      </form>
    </div>
    
  )
}

export default EditTask
 

Заранее спасибо

Ответ №1:

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

Обновить:

Что-то вроде этого,

 const params  = useParams();
const [text, setText] = useState(params.text??'');
 

Предполагая, что вы получите text собственность от своего params . Если не установлено значение по умолчанию. Параметры являются частью вашего URL-адреса, и из вашего вопроса не ясно, что исходные данные поступают из частей URL-адреса или в виде строки запроса. Поэтому я предположил, что у вас есть URL-адрес, и вы получаете некоторые значения как часть своего URL-адреса.

Обновление 2:

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

 //Get Request
  useEffect(() => {
    const getTask = async () => {
      const tasksFromServer = await fetchTask()
// Set state here so you will override the default values..
      setTask(tasksFromServer)
      setText(tasksFromServer.text);
       setDay(tasksFromServer.day);
       setReminder(tasksFromServer.reminder);

      console.log("tasksFromServer", tasksFromServer);
    }
    getTask()
  },[])
 

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

1. const [text, setText] = useState(task.text) вот так? Это не сработало

2. Я обновил свой ответ. Предполагая, что у вас есть некоторые значения, params которые вы получаете от своего маршрута.

3. Единственные параметры, которые я путаю, — это идентификатор. Текст, день и напоминание-это состояния. Другими словами localhost:3000/tasks/sometext , не существует. Единственный параметр, который я использую, — это :id

4. Итак, где же данные, которые вы хотите предварительно заполнить?

5. Это предупреждения. Вы можете игнорировать или добавлять эту функцию в качестве зависимой. Каждый раз, когда ваш компонент визуализируется, будет создаваться новый экземпляр этой функции, поэтому она будет вызывать эффект использования. Вот почему мы используем useCallback с этими зависимыми функциями. Вы можете прочитать о них перед использованием.