reactjs - tag - react render state




ReactJS: Aviso: setState(…): Não é possível atualizar durante uma transição de estado existente (6)

Estou tentando refatorar o seguinte código da minha exibição de renderização:

<Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChange.bind(this,false)} >Retour</Button>

para uma versão em que a ligação está dentro do construtor. A razão disso é que a vinculação na exibição de renderização me causará problemas de desempenho, especialmente em telefones celulares de última geração.

Eu criei o código a seguir, mas estou constantemente recebendo os seguintes erros (muitos deles). Parece que o aplicativo entra em loop:

Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.

Abaixo está o código que eu uso:

var React = require('react');
var ButtonGroup = require('react-bootstrap/lib/ButtonGroup');
var Button = require('react-bootstrap/lib/Button');
var Form = require('react-bootstrap/lib/Form');
var FormGroup = require('react-bootstrap/lib/FormGroup');
var Well = require('react-bootstrap/lib/Well');

export default class Search extends React.Component {

    constructor() {
        super();

        this.state = {
            singleJourney: false
        };

        this.handleButtonChange = this.handleButtonChange.bind(this);
    }

    handleButtonChange(value) {
        this.setState({
            singleJourney: value
        });
    }

    render() {

        return (
            <Form>

                <Well style={wellStyle}>

                    <FormGroup className="text-center">

                        <ButtonGroup>
                            <Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChange(false)} >Retour</Button>
                            <Button href="#" active={this.state.singleJourney} onClick={this.handleButtonChange(true)} >Single Journey</Button>
                        </ButtonGroup>
                    </FormGroup>

                </Well>

            </Form>
        );
    }
}

module.exports = Search;

A solução que eu uso para abrir o Popover para componentes é o reacttstrap (componentes do React Bootstrap 4) .

    class Settings extends Component {
        constructor(props) {
            super(props);

            this.state = {
              popoversOpen: [] // array open popovers
            }
        }

        // toggle my popovers
        togglePopoverHelp = (selected) => (e) => {
            const index = this.state.popoversOpen.indexOf(selected);
            if (index < 0) {
              this.state.popoversOpen.push(selected);
            } else {
              this.state.popoversOpen.splice(index, 1);
            }
            this.setState({ popoversOpen: [...this.state.popoversOpen] });
        }

        render() {
            <div id="settings">
                <button id="PopoverTimer" onClick={this.togglePopoverHelp(1)} className="btn btn-outline-danger" type="button">?</button>
                <Popover placement="left" isOpen={this.state.popoversOpen.includes(1)} target="PopoverTimer" toggle={this.togglePopoverHelp(1)}>
                  <PopoverHeader>Header popover</PopoverHeader>
                  <PopoverBody>Description popover</PopoverBody>
                </Popover>

                <button id="popoverRefresh" onClick={this.togglePopoverHelp(2)} className="btn btn-outline-danger" type="button">?</button>
                <Popover placement="left" isOpen={this.state.popoversOpen.includes(2)} target="popoverRefresh" toggle={this.togglePopoverHelp(2)}>
                  <PopoverHeader>Header popover 2</PopoverHeader>
                  <PopoverBody>Description popover2</PopoverBody>
                </Popover>
            </div>
        }
    }


Estou dando um exemplo genérico para melhor entendimento. No código a seguir

render(){
    return(
      <div>

        <h3>Simple Counter</h3>
        <Counter
          value={this.props.counter}
          onIncrement={this.props.increment()} <------ calling the function
          onDecrement={this.props.decrement()} <-----------
          onIncrementAsync={this.props.incrementAsync()} />
      </div>
    )
  }

Ao fornecer adereços, eu estou chamando a função diretamente, este wold tem uma execução de loop infinita e daria a você esse erro. Remova a chamada de função, tudo funciona normalmente.

render(){
    return(
      <div>

        <h3>Simple Counter</h3>
        <Counter
          value={this.props.counter}
          onIncrement={this.props.increment} <------ function call removed
          onDecrement={this.props.decrement} <-----------
          onIncrementAsync={this.props.incrementAsync} />
      </div>
    )
  }

Eu recebi o mesmo erro quando estava ligando

this.handleClick = this.handleClick.bind(this);

no meu construtor quando handleClick não existia

(Eu a apaguei e deixei acidentalmente a declaração "this" em meu construtor).

Solução = remova a instrução de ligação "this".


Parece que você acidentalmente está chamando o método handleButtonChange no seu método de renderização, provavelmente você deseja fazer onClick={() => this.handleButtonChange(false)} .

Se você não deseja criar um lambda no manipulador onClick, acho que precisará de dois métodos vinculados, um para cada parâmetro.

No constructor :

this.handleButtonChangeRetour = this.handleButtonChange.bind(this, true);
this.handleButtonChangeSingle = this.handleButtonChange.bind(this, false);

E no método de render :

<Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChangeSingle} >Retour</Button>
<Button href="#" active={this.state.singleJourney} onClick={this.handleButtonChangeRetour}>Single Journey</Button>

Se você estiver tentando adicionar argumentos a um manipulador em recompose , verifique se está definindo seus argumentos corretamente no manipulador. É essencialmente uma função com curry, portanto, você deve ter certeza de exigir o número correto de argumentos. Esta página tem um bom exemplo de uso de argumentos com manipuladores.

Exemplo (no link):

withHandlers({
  handleClick: props => (value1, value2) => event => {
    console.log(event)
    alert(value1 + ' was clicked!')
    props.doSomething(value2)
  },
})

para o seu filho HOC e nos pais

class MyComponent extends Component {
  static propTypes = {
    handleClick: PropTypes.func, 
  }
  render () {
    const {handleClick} = this.props
    return (
      <div onClick={handleClick(value1, value2)} />
    )
  }
}

isso evita gravar uma função anônima do manipulador para corrigir o problema, sem fornecer nomes de parâmetros suficientes no manipulador.





setstate