#reactjs #typescript #next.js
#reactjs #typescript #next.js
Вопрос:
Всем привет!
У меня проблема — setState не работает в моем приложении NextJS TS.
Я попробовал свое состояние через ReactHooks, но ничего не получилось, изменил компонент на классы, но ничего не получилось.
Я попытался запустить этот компонент во вновь созданном приложении CRA без TS. Там все работало.
Компонент получает массив через props и отображает его в виде кнопок.
Состояние содержит два свойства: currentActive и selected .
Когда пользователь нажимает на кнопку, запускается первая функция, которая должна обновить this.state.currentActive, а
затем вторая, которая должна обновить this.state.selected
В функции this.setState я вызываю обратный вызов, который должен вывести на консоль сообщение о том, что состояние было обновлено. Но ничего не выводится, это выглядит так.setState не вызывается!
import React, { Component } from 'react';
import { SelectFieldComp } from './styles';
interface IProps {
title: string;
name: string;
options: {
id: number;
text: string;
active: boolean;
}[];
multiple?: boolean;
setFieldValue?: any;
}
interface IState {
currentActive: number[];
selected: string[];
}
class SelectField extends Component<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
currentActive: [],
selected: []
};
}
updateCurrentActive = id => {
const { multiple } = this.props;
const { currentActive } = this.state;
const newCurrentActive: number[] = multiple
? Object.assign([], currentActive)
: [];
if (multiple amp;amp; newCurrentActive.indexOf(id) > 0) {
newCurrentActive.splice(newCurrentActive.indexOf(id), 1);
} else {
newCurrentActive.push(id);
}
this.setState(
() => ({ currentActive: newCurrentActive }),
() => {
console.log('update state in updateCurrentActive: ', this.state);
}
);
};
updateSelected = () => {
const { currentActive } = this.state;
const { options } = this.props;
const newArr: string[] = [];
options.forEach(item => {
if (currentActive.indexOf(item.id) > 0) {
newArr.push(item.text);
}
});
this.setState(
() => ({ selected: newArr }),
() => {
console.log('update state in updateSelected: ', this.state);
}
);
};
render() {
const { currentActive, selected } = this.state;
const { title, name, options, setFieldValue } = this.props;
return (
<SelectFieldComp>
<h3>{title}</h3>
<div>
{options.map(({ id, text }) => {
const classList = currentActive.indexOf(id) > 0 ? 'active' : '';
return (
<button
key={id}
type="button"
className={classList}
onClick={() => {
this.updateCurrentActive(id);
this.updateSelected();
setFieldValue(name, selected);
}}
>
{text}
</button>
);
})}
</div>
</SelectFieldComp>
);
}
}
export default SelectField;
Ответ №1:
Первый параметр this.setState()
— это объект, и похоже, что вы передаете функцию.
Попробуйте
this.setState({ currentActive: newCurrentActive });
Немедленное ведение журнала консоли после вызова setState также не будет работать, поскольку внутренние компоненты setState являются асинхронными, поэтому они могут быть еще не установлены.
Вы могли console.log
бы использовать свой метод рендеринга после this.props
того, как это покажет состояние при повторном рендеринге компонента.
Комментарии:
1. Это тоже не работает. Массивы currentActive и selected не подходят. Я делаю console.log (this.state) в начале моего render() {} и всегда есть пустые массивы