Где переданные аргументы сохраняются в отреагированном компоненте - PullRequest
0 голосов
/ 05 ноября 2018

Я следил за некоторыми уроками на веб-сайте реагирования и попробовал несколько примеров кода. Вот ссылка на этот код в codepen

https://codepen.io/gaearon/pen/gWWZgR?editors=0010

Вот некоторые фрагменты проблемы

<div className="board-row">
    {this.renderSquare(0)}
    {this.renderSquare(1)}
    {this.renderSquare(2)}
</div>

Это вызовет метод renderSquare , передающий число в качестве аргумента, поэтому это будет полезно для идентификации метода onClick в зависимости от square (который является кнопкой).

Вот метод renderSquare

renderSquare(i) {
        console.log(<Square/>);
        return (
            <Square
                value={this.props.squares[i]}
                onClick={() => this.props.onClick(i)}
            />
        );
    }

и этот метод вызывает функциональный компонент Квадрат ,

function Square(props) {
    return (
        <button className="square" onClick={props.onClick}>
            {props.value}
        </button>

    );
}

Таким образом, при нажатии на квадрат вызывается метод handleClick (i) (лучше увидеть ссылку codepen , чтобы вы понимали весь код)

handleClick(i) {
        console.log(i);
        const history = this.state.history.slice(0, this.state.stepNumber + 1);
        const current = history[history.length - 1];
        const squares = current.squares.slice();
        if (calculateWinner(squares) || squares[i]) {
            return;
        }
        squares[i] = this.state.xIsNext ? "X" : "O";
        this.setState({
            history: history.concat([{
                squares: squares,
            }]),
            stepNumber: history.length,
            xIsNext: !this.state.xIsNext,
        });
    }

Таким образом, используя этот console.log (не в коде кода) , когда я нажимаю кнопку (игра в крестики-нолики, 9 кнопок), она показывает аргумент, который передан (0 1,2 ... 8).

Итак, мой вопрос: где эти числа хранятся в этих отреагированных компонентах реакции? Я пробовал консольный компонент Square, но я не смог найти этот аргумент. (Это не связано с реквизитом или состоянием)

Ответы [ 3 ]

0 голосов
/ 05 ноября 2018

Итак, мой вопрос: где эти числа хранятся в этих отреагированных компонентах реакции?

Это не имеет ничего общего с React. Так работают функции в JavaScript.

Всякий раз, когда функция вызывается, создается новая среда. Среда - это внутренняя структура данных, сохраняющая состояние (не путать с состоянием компонента React!). Значения параметров и переменных хранятся в этой среде.

Например, рассмотрим функцию:

function foo(bar) {
  var baz = 42;
}

foo(21);

Когда вызывается foo, создается новая среда с двумя записями:

<foo environment>
bar: 21
baz: 42

Примечание: Вызовы функций изолированы. Каждый раз, когда вызывается функция, для этого вызова создается новая среда.


В вашем коде

Каждый раз, когда вызывается renderSquare, создается новая среда с записью i.


Замыкания - это функции, которые могут разрешать переменные, которые не определены сами по себе. Рассмотрим следующий пример:

function add(x) {
  return function innerAdd(y) {
    return x + y;
  }
}

var add5 = add(5);
add5(2); // 7

Здесь innerAdd ссылается на x, но x не определяется внутри себя, это ' Вместо этого определяется "далее вверх" в add.

При выполнении add создается новая среда с

<add environment>
x: 5

innerAdd имеет ссылку на эту среду! Поэтому, когда add5 / innerAdd выполняется, он может искать x в этой среде. Вы можете думать о средах, связанных друг с другом:

<innerAdd environment>
y: 2
parentEnvironment:
  <add environment>
  x: 5

Сначала мы увидим, определено ли x в <innerAdd environment>. Поскольку это не так, мы смотрим на его родителя и т. Д.


В вашем коде

Точно так же происходит с обработчиком событий, который вы создаете внутри renderSquare. Обработчик событий - это функция, которая создается внутри среды, в которой i=0 (и / или i=1, i=2 и т. Д.).


Вот упрощенный пример, в котором не используется React:

function createButton(i) {
  const button = document.createElement('button');
  button.textContent = 'Click me';
  button.onclick = () => console.log(i);
  document.body.appendChild(button);
}

createButton(0);
createButton(1);
createButton(2);

Chrome позволяет проверять окружение (я), связанные с функцией. Например:

enter image description here

Это показывает, что обработчик событий был создан внутри createButton, где i имеет значение 0.

См. Также Как работают закрытия JavaScript?

0 голосов
/ 06 ноября 2018

Они хранятся в состоянии, также функция onclick уже имеет индекс:

() => this.props.onClick(i)// line 16 in your code

i - это индекс, который вы указали, и он останется в этой функции как часть этой функции. Функции являются контекстно-зависимыми, поэтому, когда вы создаете функцию (замыкание) в одном контексте, она наследует контекст, в котором она была создана. Таким образом, я всегда буду там для этой функции, даже если она была определена вне замыкания.

Кроме того, цель упражнения - показать вам, как управлять изменением состояния и как его хранить, что делается в коде, а не в автоматическом реагировании. Всякий раз, когда действие выполняется, все состояние (включая этот индекс) сохраняется в истории.

0 голосов
/ 05 ноября 2018

в методе handleClick, выйдите из системы history, и вы увидите, что данные сохранены в состоянии, в данном случае this.state.history. попробуйте это:

handleClick(i) {
    const history = this.state.history.slice(0, this.state.stepNumber + 1);
    const current = history[history.length - 1];
    console.log('history:', history)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...