Pesquisa de site

reactjs - Por que o setState não funcionou neste caso no NextJS?


Olá a todos!
Eu tenho um problema - setState não funciona na minha aplicação NextJS + TS.
Eu tentei meu estado através de ReactHooks, mas nada funcionou, transformei o componente em classes, mas nada funcionou.
Eu tentei rodar este componente em uma aplicação CRA recém-criada sem TS. Tudo funcionou lá.

O componente recebe o array via props e o renderiza como botões.
O estado contém duas propriedades, currentActive e selected.
Quando o usuário clica no botão, a primeira função é acionada, a qual deveria atualizar this.state.currentActive
depois a segunda função, que deveria atualizar this.state.selected

Na função this.setState, eu chamo um callback, que deveria imprimir no console que o estado foi atualizado. Mas nada é exibido, parece que o this.setState não está sendo chamado!

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 && 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;

Resposta #1

O primeiro parâmetro de this.setState() é um objeto e parece que você está passando uma função.

Tentar

 this.setState({ currentActive: newCurrentActive });

Fazer um console log imediatamente após chamar setState também não funcionará, pois os detalhes internos do setState são assíncronos e podem ainda não estar definidos.

Você poderia usar console.log no seu método render após this.props, pois isso mostrará o estado na re-renderização do componente.