Метод toString
, который вы вводите в State, связан с исходным экземпляром состояния:
class State {
constructor(xs) { this.xs = xs }
toString = () => `[${this.xs}]` // Class field arrow function
}
Поле класса там означает, что независимо от того, какой контекст вызова вызывается toString
вызывается с помощью, он вернет this.xs
исходного состояния. Даже если редуктор обновляет состояние, конструктор состояния не запускается снова .
При последующих вызовах App
создается начальное состояние, а затем выполняется несколько действий для обновления. это, в результате переменная state
является обновленным объектом, , но у него все еще есть метод toString
, связанный с начальным состоянием .
Вот пример поведения в vanilla JS:
const obj = {
val: 'val',
toString: () => obj.val
};
const copiedObj = { ...obj, val: 'newVal' };
console.log(copiedObj.toString());
Если вы назначили function
вместо функции стрелки, то toString
будет вызываться с контекстом вызова обновленного состояния *1029* потому что он не связан с начальным состоянием, поэтому он будет вызываться с контекстом вызова обновленного состояния и правильно извлекать xs
:
toString = function () {
return `[${this.xs}]`;
}
Как примечание, вы не можете используйте обычный метод как
toString() {
return `[${this.xs}]`;
}
, потому что в вашем редукторе:
const reducer = (state, action) => ({
...state,
xs: [...state.xs, action.x]
});
синтаксис распространения принимает только перечислимых собственных свойств. С синтаксисом метода (например, toString() {
) свойство помещается в прототип State , а не в фактический экземпляр, поэтому он не будет существовать в конечном state
, и вместо этого будет вызываться встроенный Object.prototype.toString
.