Учебное пособие: связь между компонентами-братьями с использованием состояния и управляемых форм

Иерархия компонентов:

Parent Component: App.js
... Child component: ExampleForm.js
... Child component: SubmittedFormInfo.js
Вход в полноэкранный режим Выход из полноэкранного режима

Цель

У меня есть пример формы в дочернем компоненте ExampleForm для получения ввода названия, url изображения и цены для нового товара. Я хочу, чтобы эта информация немедленно отображалась в другом дочернем компоненте SubmittedFormInfo, без необходимости обновлять страницу.

Оба этих компонента являются дочерними компонентами App, но информация не может быть передана напрямую между такими компонентами, как эти. Как мы можем взять информацию из формы, а затем сразу же отобразить ее в другом компоненте?

Прогулка

Этот вопрос зависит от использования функций state и setter, передаваемых в качестве реквизитов каждому из компонентов. Поскольку информация не может быть передана напрямую между родственными компонентами, нам необходимо использовать состояние в родительском компоненте, которое будет передавать информацию каждому из двух компонентов, чтобы данные могли быть отображены.

Компонент приложения
Начните с использования хука useState в компоненте App и используйте начальное значение пустого объекта, который в конечном итоге будет содержать информацию из нашего примера формы:

function App() {

const [newItem, setNewItem] = useState({})
Вход в полноэкранный режим Выход из полноэкранного режима

Нас пока не слишком волнует фактическое значение newItem. Вместо этого начнем с передачи функции-сеттера setNewItem компоненту ExampleForm. Первая цель здесь заключается в том, что мы хотим изменить значение newItem при отправке формы с помощью переданной функции-сеттера:

<ExampleForm setNewItem={setNewItem}/>
Войти в полноэкранный режим Выход из полноэкранного режима
function ExampleForm({ setNewItem }) {
Войти в полноэкранный режим Выйти из полноэкранного режима

Компонент ExampleForm
Прежде чем двигаться дальше, нам нужно использовать управляемую форму для отслеживания данных, вводимых пользователем. Для простоты объявим три начальных значения в виде пустых строк для каждого поля ввода на форме с помощью хука useState:

function ExampleForm({ setNewItem }) {

  const [name, setName] = useState('')
  const [image, setImage] = useState('')
  const [price, setPrice] = useState('')
Войти в полноэкранный режим Выход из полноэкранного режима

Они будут использоваться в качестве значений для каждого ввода в форме примера следующим образом:

<form>
    <input type="text" name="name" placeholder="Name" value={name} />
    <input type="text" name="image" placeholder="Image URL" value={image} />
    <input type="number" name="price" placeholder="Price" value={price} />
    <button type="submit">Add Item</button>
</form>
Войти в полноэкранный режим Выйти из полноэкранного режима

Для управляемых форм каждое изменение, которое пользователь вносит в поле ввода, должно обновлять состояние, чтобы отслеживать информацию, введенную пользователем. Это особенно полезно для немедленного использования информации, например, когда вы хотите, чтобы соответствующие элементы отображались в DOM с помощью строки поиска по мере ввода пользователем. Даже если нам нужна эта информация только при отправке, все равно полезно использовать контролируемую форму. Чтобы сделать эту форму управляемой, начните с объявления трех отдельных функций для обработки изменений в каждом из полей ввода. В каждой функции мы хотим использовать функции-установщики setName, setImage и setPrice из состояния этого компонента. Каждая функция должна обновлять состояние, используя объект события, для доступа к данным о каждой введенной в форму букве:

function handleNameChange(event) {
    setName(event.target.value)
  }

function handleImageChange(event) {
    setImage(event.target.value)
  }

function handlePriceChange(event) {
    setPrice(event.target.value)
  }
Вход в полноэкранный режим Выход из полноэкранного режима

Чтобы вызвать эти функции, когда пользователь вводит данные, используйте эти функции в качестве обратных вызовов для событий onChange в каждом из полей ввода формы:

<form>
    <input type="text" name="name" placeholder="Name" value={name} onChange={handleNameChange}/>
    <input type="text" name="image" placeholder="Image URL" value={image} onChange={handleImageChange}/>
    <input type="number" name="price" placeholder="Price" value={price} onChange={handlePriceChange}/>
    <button type="submit">Add Item</button></form>
Войти в полноэкранный режим Выйти из полноэкранного режима

Общая идея заключается в том, что по мере ввода пользователем данных каждая из этих функций будет вызываться для обновления состояния. Поскольку мы используем переменные состояния в качестве входных значений в форме, значения формы будут обновляться по мере обновления состояния с помощью функций-обработчиков. Когда пользователь закончит вводить текст, у нас будет полная информация, доступная для использования в каждой из переменных состояния name, image и price.

Когда пользователь отправляет форму, мы хотим изменить значение newItem, объявленное в App, используя информацию, введенную пользователем. Мы можем сделать это, вызвав функцию-сеттер setNewItem, которая была передана компоненту формы в качестве реквизита. Начните с объявления функции handleSubmit, которая должна вызываться, когда пользователь отправляет форму с помощью функции onSubmit в открывающем теге формы. В функции handleSubmit мы хотим создать новый объект, указав пары ключ/значение, используя переменные состояния в качестве каждого значения, следующим образом:

const formData = {
      name: name,
      image: image,
      price: parseInt(price)
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем вызовите setNewItem, используя объект formData в качестве указанного значения:

setNewItem(formData)
Войти в полноэкранный режим Выйти из полноэкранного режима

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

function handleSubmit(event) {
    event.preventDefault();

    const formData = {
      name: name,
      image: image,
      price: parseInt(price)
    }

    setNewItem(formData)

    setName('')
    setImage('')
    setPrice('')
 }
Вход в полноэкранный режим Выход из полноэкранного режима

Основной строкой кода, на которой следует сосредоточиться, является setNewItem(formData). Это обновляет состояние в родительском компоненте App, что позволяет нам затем передать данные формы в SubmittedFormInfo как дочерний компонент App.

Компонент SubmittedFormInfo
Чтобы окончательно отобразить данные формы в нашем приложении, в компоненте App передайте newItem как свойство в SubmittedFormInfo:

<SubmittedFormInfo newItem={newItem}/>
Войти в полноэкранный режим Выход из полноэкранного режима

newItem теперь содержит объект с названием, url изображения и ценой товара, добавленного пользователем. Пусть SubmittedFormInfo получает реквизит и, по желанию, деструктурирует newItem для более удобного использования информации, содержащейся в объекте newItem.

function SubmittedFormInfo({ newItem }) {

  const {name, image, price} = newItem
Вход в полноэкранный режим Выход из полноэкранного режима

Все, что осталось сделать, это отобразить в DOM переменные имени, изображения и цены:

return (
    <header>
      <h2>
        Submitted Form Data
      </h2>
      <p>Name: {name}</p>
      <p>Image url: {image}</p>
      <p> Price: ${price}</p>
    </header>
  );
}
Вход в полноэкранный режим Выход из полноэкранного режима

Благодаря этому добавлению, после того, как пользователь отправит форму, информация, введенная пользователем, должна автоматически отобразиться в DOM. Это происходит из-за обновления состояния. Поскольку SubmittedFormInfo зависит от переменной newItem в состоянии, как только значение newItem обновится, это заставит компонент SubmittedFormInfo перерисоваться, немедленно отображая информацию, введенную пользователем.

Заключение

Мы использовали newItem и его функцию-сеттер для обновления приложения. Мы начали с передачи функции ‘setNewItem’ в ExampleForm, которая вызывалась, когда пользователь отправлял форму. По мере того как пользователь набирал текст, состояние компонента формы обновлялось, отслеживая значения, введенные пользователем. После отправки формы мы установили значение newItem на данные, введенные пользователем. Это вызвало обновление состояния newItem, которое было передано в наш контейнер отображения в качестве свойства. Затем этот компонент повторно отображался при отправке, отображая информацию, введенную пользователем, непосредственно под формой, без необходимости обновлять страницу.

Оцените статью
devanswers.ru
Добавить комментарий