Вам бы основы
JavaScript подтянуть.
Во-первых вы биндите контекст хандлера на
AppField в конструкторе:
constructor(props) {
super(props);
this.state = props.params;
this.onFieldChange = this.onFieldChange.bind(this); // тут
}
Во-вторых, вы определяте переменную
self, ссылающуюся на
this и она ни делает ровным счетом ничего, так как вы передаете функцию в колбек обработчика события:
renderSingleValue(data = {}) {
...
let self = this; // бессмысленно
return (
<input type="text"
...
onChange={self.onFieldChange}
...
/>
);
}
Даже если бы функция не была забинжена на
AppField, у вас бы все-равно ничего не получилось.
В-третих, значение инпутов лучше хранить в родителе, а не в самих инпутах.
Трюк с
self работает в отложенных вызовах:
constructor() {
const self = this;
node.addEventListener('click', function() {
self.handleEvent(); // сработает, так как функция вызывается на self
});
}
и не сработает при передаче функции:
constructor() {
const self = this;
node.addEventListener('click', self.handleEvent); // не сработает, функция передается
// в колбек обработчика события
} // и не будет вызываться на self
Пример как можно сделать контролируемую форму с состоянием инпутов в родителе:
class Example extends Component {
state = {
inputValue: '',
};
handleChange = e => { // arrow class field function биндится на контекст экземпляра
const { name, value } = e.target;
this.setState({
[name]: value,
});
};
render() {
const { inputValue } = this.state;
return (
<Wrapper>
<input
name="inputValue"
value={inputValue}
onChange={this.handleChange}
/>
...
</Wrapper>
);
}
}
Аналогичное решение без использования
class field function:
class Example extends Component {
constructor(props) {
super(props);
this.state = {
inputValue: '',
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
const { name, value } = e.target;
this.setState({
[name]: value,
});
}
render() {
const { inputValue } = this.state;
return (
<Wrapper>
<input
name="inputValue"
value={inputValue}
onChange={this.handleChange}
/>
...
</Wrapper>
);
}
}
Если делаете совой компонент вроде кастомного
select, то вы можете в его реализации по изменению сами вызывать хандлер
onChange, передавая туда фейковое событие с нужными вам ключами:
handleChange = value => {
const { name, onChange } = this.props;
const fakeEvent = { target: { name, value } };
onChange(fakeEvent);
};