Javascript-форум (https://javascript.ru/forum/)
-   Библиотеки/Тулкиты/Фреймворки (https://javascript.ru/forum/library-toolkit-framework/)
-   -   React. Проблема с передачей event-объекта при обновлении стейта в input'e (https://javascript.ru/forum/library-toolkit-framework/76231-react-problema-s-peredachejj-event-obekta-pri-obnovlenii-stejjta-v-input%27e.html)

Leonid_ts 15.12.2018 18:44

React. Проблема с передачей event-объекта при обновлении стейта в input'e
 
Изучаю реакт неделю и столкнулся со следующей проблемой (ссылка на CodePen).

Есть два инпута - имейл и пароль. В них есть один обработчик осбытия onChange. В нем при каждом изменении value происходит обновление стейта компонента. И проблема заключается в том, что если обновлять стейт через функцию
handleChange = (e) => {
    this.setState(state => ({
      ...state,
      [e.target.type]: e.target.value,
    }));
 }

то, почему-то появляется ошибка "Cannot read property 'type' of null". Т.е. объект события передается с пустыми свойствами.

Однакому если деструктуризовать объект события, то всё работает
const { target } = { ...e };

this.setState(state => ({
  ...state,
  [target.type]: target.value,
}));


или так

const { target } = { ...e };
const { type } = target;
const { value } = target;

this.setState(state => ({
  ...state,
  [type]: value,
}));


Если менять стейт не в функциональном стиле, то объект события имеет правильные свойства
this.setState({
    ...this.state,
    [e.target.type]: e.target.value,
});


Вопрос: почему без структуризации, функция которая обновляет стейт получает объект события с пустыми полями. Деструтурированный объект traget (и его деструктурированные свойства) и объект e находятся же в одной области видимости. Что я упускаю?

Если можете распишите, пожалуйста, максимально подробно. Я только учусь и могу не знать очевидные для опытных программитов вещей.

SuperZen 16.12.2018 09:52

Хороший вопрос %)

http://www.ecma-international.org/ec...ics-evaluation

An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment...

Leonid_ts 16.12.2018 14:59

SuperZen,
За ссылку, спасибо, но всё равно не понимаю. То ли не хватает понимания английского, то ли просто не понимаю того, как это объясняется в источнике. Что значит "Стрелочная функция не определяет локальной привязки для arguments(иммется ввиду список агрментов, не объект же arguments?), super, this, or new.target.". Как это не определяет, если тут
let f = (outerArg) => {
    let fInner = (innerArg) => {
        console.log(outerArg);
        console.log(innerArg);
    }
    fInner('inner arrowFunc argument');
}
f('outer arrowFunc argument');

чудесно выведется в консоль и outerArg и innerArg;

SuperZen 17.12.2018 10:23

хз что там внутри, делает реакт, может быть копию ) ф-ции... если только в IIFE завернуть
class App extends Component {

  state = {
    one: 1
  }

  onChange = (e) => {
    this.setState(((state) => {
      return ({ [e.target.name]: e.target.value })
    })(), () => console.log(this.state))
  }

  render() {
    return (
      <div className="App">
        <input type="text" name="one" value={this.state.one} onChange={this.onChange} />
      </div>
    );
  }
}


setState внутри...
setState<K extends keyof S>(
            state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
            callback?: () => void
        ): void;

Leonid_ts 18.12.2018 19:04

SuperZen,
нашел ответ, но всё равно не понимаю, как мы можем получить доступ к "правильным" свойствам объекта, после того, как они были обnullены.

SuperZen 18.12.2018 20:50

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


Часовой пояс GMT +3, время: 19:42.