ReactJS: Advertencia: setState (…): no se puede actualizar durante una transición de estado existente

Estoy tratando de refactorizar el siguiente código desde mi vista de renderizado:

 

a una versión donde el enlace está dentro del constructor. La razón de esto es que vincular en la vista de procesamiento me dará problemas de rendimiento, especialmente en teléfonos móviles de gama baja.

He creado el siguiente código, pero constantemente recibo los siguientes errores (muchos de ellos). Parece que la aplicación se pone en un bucle:

 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`. 

A continuación está el código que 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 ( 
); } } module.exports = Search;

Parece que estás llamando accidentalmente al método handleButtonChange en tu método de renderización, es probable que quieras hacer onClick={() => this.handleButtonChange(false)} lugar.

Si no desea crear un lambda en el controlador onClick, creo que deberá tener dos métodos vinculados, uno para cada parámetro.

En el constructor :

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

Y en el método de render :

   

From reactjsr documentos Pasando argumentos a controladores de eventos

   

Si intenta agregar argumentos a un controlador en la recompose , asegúrese de que está definiendo correctamente sus argumentos en el controlador. Es esencialmente una función curried, por lo que debe asegurarse de requerir la cantidad correcta de argumentos. Esta página tiene un buen ejemplo del uso de argumentos con controladores.

Ejemplo (del enlace):

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

para su hijo HOC y en el padre

 class MyComponent extends Component { static propTypes = { handleClick: PropTypes.func, } render () { const {handleClick} = this.props return ( 
) } }

esto evita escribir una función anónima fuera de su controlador para corregir el problema al no proporcionar suficientes nombres de parámetros en su controlador.

Recibí el mismo error cuando estaba llamando

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

en mi constructor cuando handleClick no existía

(Lo había borrado y había dejado accidentalmente la statement vinculante “this” en mi constructor).

Solución = eliminar la statement vinculante “this”.

La solución que uso para abrir Popover para componentes es reactstrap (componentes 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() { 
Header popover Description popover Header popover 2 Description popover2
} }

El problema es, sin duda, este enlace mientras se desgarra el botón con el controlador onClick. La solución es usar la función de flecha al llamar al manejador de acción durante el renderizado. De esta manera: onClick={ () => this.handleButtonChange(false) }