Как React реализует свою двустороннюю привязку данных? - PullRequest
0 голосов
/ 20 октября 2018

Я видел примеров , показывающих, как реализовать двустороннее связывание в React, но никто не объясняет, как эта функция на самом деле функционирует внутри.

В этом примере codepen взято с веб-сайта React, если вы закомментируете строку 11:

handleChange(event) {
  // this.setState({value: event.target.value});
}

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

Учитывая, что event.target.value имеет ввод, который пользователь только что ввел в область действия handleChange, но, тем не менее, становится пустым в представлении, это означает, что в какой-то момент значение было сброшенопо реакции.Кроме того, это не просто сброс значения на пустое, а в соответствии с последней моделью данных, это можно проверить, внеся следующие изменения в код:

constructor(props) {
  super(props);
  this.state = {value: ''};

  this.handleChange = this.handleChange.bind(this);
  this.handleSubmit = this.handleSubmit.bind(this);

  this.counter = 0;
}

handleChange(event) {
  if (this.counter < 3) {
    this.setState({value: event.target.value});
    this.counter++;
  }
}

На этот раз поле ввода изменяет первые тривремя от времени, а затем сбрасывается в соответствии с последним состоянием модели.

Мне кажется следующее:

  1. Элемент HTML изменяется в соответствии с пользовательским вводом.
  2. Обработчик события "onchange" сработал.
  3. Состояние НЕ обновлено.
  4. Поскольку состояние не было обновлено, React отображает кэшированное представление компонента Virtual-DOM для элемента Real-DOMэто было только что изменено пользователем.
  5. React обновляет атрибуты элемента Real-DOM в соответствии с его представлением Virtual-DOM.

Если состояние было изменено, токэшированное представление Virtual-DOM было бы «загрязнено», и это вызвало бы повторную визуализацию виртуального элемента.Тем не менее, остальная часть потока, который я описал выше, все равно будет применяться, означая, что новый HTML-узел не был бы создан, и только атрибуты существующего были бы обновлены (при условии, что тип элемента, например, <input>, didn 'изменить).

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

Спасибо!

Ответы [ 2 ]

0 голосов
/ 12 июля 2019

Я покажу на примере, как работает двусторонняя привязка React.Настройка приложения React

App.js

import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';


class App extends Component {

  state = {
    persons: [
      {
        name: "VK",
        age: 29
      },
      {
        name: "HK",
        age: 28
      }
    ]
  }

  nameChangedHandler = (event) => {
    this.setState(
      {
        persons: [
          {
            name: "VK",
            age: 29
          },
          {
            name: event.target.value,
            age: 28
          }
        ],
        groupName: "Vishita"
      }
    );
  }

  render() {
    return (
      <div className="App">
        <h1>Vinit Khandelwal</h1>
        <p>And here is my resume</p>
        <Person 
        name={this.state.persons[0].name} 
        age={this.state.persons[0].age} />
        <Person 
        name={this.state.persons[1].name} 
        age={this.state.persons[1].age} 
        changed={this.nameChangedHandler} >Hobby: Shopping</Person>
      </div>
    );
  }
}

export default App;

Person> Person.js

import React from 'react';

const person = (props) => {
    return (
        <div>
            <p>I am {props.name}. I am {props.age} years old!</p>
            <p onClick={props.click}>{props.children}</p>
            <input type="text" onChange={props.changed} value={props.name} />
        </div>
    );
}

export default person;

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

0 голосов
/ 20 октября 2018

Это аккуратный вопрос, и я сделаю все возможное, если кто-то увидит какие-либо ошибки в моем ответе, укажите их, и я с удовольствием отредактирую исправления!Копаясь в источнике React, вот что я придумала:

1 - HTML изменен и в DOM вызывается событие

2 - React ставит в очередь отправку события / синтетического события внутри EventPropoagators.js

3 - события удаляются по порядку (это событие не влияет на состояние)

4 - в конце цикла событий реагирует использованиеrestoreTarget для восстановления контролируемых компонентов для представления состояния в React Controlled Component.js :

Используется для восстановления контролируемого состояния после возникновения события изменения.

Мы выполняем этот перевод в конце цикла событий, чтобы мы всегда получали правильное волокно здесь

Вот где происходит волшебство.restoreTarget является компонентом state, поэтому реакция запускает регулярный render() в этот момент, чтобы перерисовать restoreTarget, который, как я думаю, будет проходить через стандартный алгоритм согласования виртуальных DOM и реальных DOM.

Согласно вашему примеру, handleChange() выполняется (с изменением состояния или без него), после чего restoreTarget перерисовывается и отображает компонент, который точно представляет состояние в тот момент, когда count = 3.

...