У меня есть компонент, который вы можете включить/выключить, нажав на него:
clickHandler = () => {
this.setState({active: !this.state.active})
this.props.getSelection(this.state.active)
}
render() {
const { key, children } = this.props;
return (
<button
key = {key}
style = {{...style.box, background: this.state.active ? 'green' : ''}}
onClick = {() => this.clickHandler()}
>
{children}
</button>
);
}
В родительском компоненте я передаю метод для пытаться и получаю значение выбранного элемента, помещенного в массив, например так:
getSelection = (val) => {
const arr = []
arr.push(val);
console.info(arr, 'arr');
}
Моя проблема в том, что он добавляет только один элемент в массив, поэтому длина массива всегда равна 1 (даже если было нажато более одного элемента).
console.info(arr, 'arr') // ["Birthday"] "arr"
console.info(arr, 'arr') // ["Birthday", "Christmas", "School achievement"] "arr"
Ссылка на Кодепен
Есть идеи?
Попробуйте определить константу arr вне функции getSelection.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Две вещи: setState является асинхронным, поэтому в следующей строке вы можете получить или не получить последнее значение, поэтому я рекомендую изменить
clickHandler = () => {
this.setState({active: !this.state.active})
this.props.getSelection(this.state.active)
}
к
clickHandler = () => {
this.setState({active: !this.state.active}, () => {
this.props.getSelection(this.state.active)
})
}
Второй аргумент setState — это функция обратного вызова, которая будет выполняться сразу после выполнения setState.
Во-вторых, в getSelection вы определяете новый массив каждый раз, когда попадаете туда, поэтому он не будет иметь значений из предыдущего запуска. Вы должны хранить его где-то.
Нет проблем, я рад, что это помогло. Если вы хотите отслеживать выбранные элементы, вам может понадобиться что-то вроде этого: Кодепен
Здесь есть 2 проблемы:
arr — локальная переменная. Он не сохраняет предыдущий результат onClick.
setState — это асинхронное событие. Согласно документация:
setState() does not always immediately update the component.
setState((state, props) => {}, () => { /*callback */}) следует использовать.
class Box extends React.Component {
state = {
active: false
};
clickHandler = () => {
this.setState(
state => ({ active: !state.active }),
() => {
this.props.getSelection(this.state.active);
}
);
};
render() {
const { children } = this.props;
return (
<button
style = {{ ...style.box, background: this.state.active ? "green" : "" }}
onClick = {this.clickHandler}
>
{children}
</button>
);
}
}
Незначительное примечание:
Значение key отсутствует в дочернем компоненте this.props, поэтому вам не нужно его передавать, но это не повлияет на результат.
В компоненте App давайте создадим массив на уровне класса для отображения:
class App extends React.Component {
state = {
needsOptions: ["Birthday", "Christmas", "School achievement"]
};
arr = [];
getSelection = val => {
this.arr.push(val);
console.info(this.arr);
};
}
каждый раз, когда вызывается
{ const arr = [] arr.push(val); console.info(arr, 'arr') }, он создает пустой массив, в который вы помещаете один элемент, так что, конечно, это всегда 1 длина — вам нужно объявитьarrза пределами этой функции