React — популярная библиотека JavaScript по многим причинам, и одна из причин — «односторонняя привязка данных». Если вы хотите понять React в его основе, вам следует читать дальше.

Для данных это дорога с односторонним движением

Приложения React состоят из тщательно организованных компонентов. Эти компоненты получают аргументы (реквизиты) и возвращают информацию, используя возвращаемое значение функции рендеринга. Когда данные передаются от родительского к дочернему компоненту, это называется однонаправленным потоком данных.

Родительский компонент передает информацию дочернему компоненту с помощью реквизита. Но также возможно, что дочернему компоненту может потребоваться что-то изменить в пользовательском интерфейсе. Что делать в таком случае?

Возможна ли передача данных от дочернего компонента к родительскому?

Что, если нажатие кнопки в дочернем компоненте изменит текст в родительском компоненте? Как убедиться, что родительский компонент знает, что нажата кнопка, которая должна изменить свой текст?

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

Пример

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

Как мы уже обсуждали, нам нужно изменить текст в родительском компоненте, который в настоящее время «Hello», на «World». Итак, это наш элемент государства.

Теперь, в каком компоненте должно жить государство? Ребенок? Родитель? Гм... так что вот несколько шагов, которые облегчат вам решение, где должно находиться состояние:

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

В нашем случае легко определить, что состояние должно находиться в компоненте «Родитель».

const [text, setText] = useState(“Hello”);

Теперь, что мы делаем с компонентом «Родительский»? Мы передаем функцию обратного вызова как реквизит родительского компонента.

<Child changeText={(text) => setText(text)} />

Теперь нам нужна функция обратного вызова в компоненте «Дочерний», которая срабатывает при нажатии кнопки.

<button onClick={() => props.changeText(“World”)}>

Со всеми отдельными элементами на месте, вот что файлы JavaScript ищут для каждого компонента:

Parent.js

import React, { useState } from “react”;
import Child from “./Child”;
function Parent(props) {
const [text, setText] = useState(“Hello”);
return (
<div>
<h1>{text}</h1>
<Child changeText={(text) => setText(text)} />
</div>
);
}
export default Parent;

Child.js

import React from “react”;
function Child(props) {
return (
<div>
<button onClick={() => props.changeText(“World”)}>
Change the text
</button>
</div>
);
}
export default Child;

App.js

import Parent from “./Parent”;
function App() {
return (
<>
<div className=”App”>
<Parent />
</>
);
}
export default App;

Как это работает?

В компоненте «Родитель» содержимое тега h1 должно меняться, изначально для него установлено значение «Hello». Теперь, когда кнопка (в дочернем компоненте) нажата, она запускает прослушиватель событий onClick, который вызывает функцию обратного вызова, переданную от «Родительского» к «Дочернему» компоненту, который изменяет текст на «Мир» и повторно отображает компонент.

Заключение

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

Эта функция обновляет состояние в родительском компоненте, и как только состояние изменяется, оно снова передается в качестве реквизита. Это позволяет компонентам повторно отображать и отображать требуемые результаты.

Здесь я объяснил передачу данных от дочернего к родительскому компоненту с помощью функциональных компонентов, того же можно добиться и с помощью компонентов класса.