2017-10-19 2 views
0

In einer einfachen reactJS-Klasse hat this.setState() den Status nicht tatsächlich festgelegt. Ich weiß, dass es asynchron aufgerufen wird, aber selbst wenn die Komponente wieder rendert, wurde der Zustand nicht mutiert. So this.state.showModal ist false wenn Komponente montiert ist (wie erwartet) dann ist es true "für immer".Warum setzt ReactJS den Status beim Aufruf von setState innerhalb von setTimeout?

hier ist ein einfaches Beispiel:

class MyComponent extends Component { 
    constructor (props) { 
    super(props) 

    this.state = { 
     showModal: false 
    } 

    this.showModal = this.showModal.bind(this) 
    this.hideModal = this.hideModal.bind(this) 
    } 
    showModal() { 
    this.setState({ showModal: true }) 
    } 
    hideModal() { 
    this.setState({ showModal: false }) 
    } 
    render() { 
    console.log(this.state.showModal) // Outputs true even after the hideModal() call 

    return (
     <Components> 
     <div onClick={this.showModal}> 
      { 
      this.state.showModal === true 
      ? <Modal 
       handles={handles} 
       close={this.hideModal} 
      /> 
      : '+' 
      } 
     </div> 
     </Components> 
    ) 
    } 
} 

Hier ist der Modal Komponente:

setTimeout(() => this.setState({ showModal: false }), 0)

:

class Modal extends Component { 
    render() { 
    return (
     <div className='configurator-modal'> 
     <button className='close' onClick={this.props.close}> x </button> 
     Modal 
     </div> 
    ) 
    } 
} 

Aber, wenn ich die hideModal Funktion mit einem Timeout wie folgt ersetzen

Der Zustand ist mutiert und rendere d wie beabsichtigt.

Ich frage mich nur, warum ReactJS möglicherweise intern den Status zurücksetzen oder einen Zustand von Mutation verhindern könnte?

Edit: Anrufe zu hideModal und ShowModal hinzugefügt

+2

Sie müssen zeigen, wie Sie 'hidemodal' aufrufen? – Panther

+0

Können Sie uns sagen, wie Sie die Methode 'hideModal' aufrufen? – vs1682

+0

Ich habe meinen Post bearbeitet, leider habe ich versucht, den Code ein wenig zu viel zu vereinfachen. – 3Dos

Antwort

0

Da gibt es keinen Plünderer zu spielen, werde ich eine Vermutung nehmen.

div wobei die Eltern von <Modal>, wenn Click-Ereignis auf dem Modal ausgelöst wird, wird es auch zu div ausbreitet. So showModal Zustand wird auf false von hideModal() Funktion eingestellt und zurück zu true von showModal() Funktion.

Wenn hideModal()setTimeout() verwendet, wird es aufgerufen, nachdem showModal() aufgerufen wird.

Versuchen Sie event.stopPropagation in hideModal() Funktion hinzufügen, könnte es funktionieren.

Alternativ können Sie showModal() als OnClick-Handler für das +-Zeichen anstelle des vollständigen übergeordneten div hinzufügen. Finden Sie den folgenden Code:

<Components> 
    <div> 
     { 
     this.state.showModal === true 
     ? <Modal 
      handles={handles} 
      close={this.hideModal} 
     /> 
     : <div onClick={this.showModal}>'+'</div> 
     } 
    </div> 
    </Components> 
+0

Vielen Dank. Das funktioniert perfekt. Ich habe absolut nicht daran gedacht, aber es scheint super Logik! – 3Dos

0

Sie haben einen click Handler für das übergeordnete Element zu dem die showModal nennen und den Staat zu wahren ändern.

Wenn Sie close Schaltfläche klicken, die hideModal Funktion aufrufen wird, die den Staat zu false ändern wird, aber das Klicken, als auch auf übergeordnete Element wird propagieren, die showModal nennen, die es wieder machen true. Daher bleibt es immer true.

Lösung:showModal Click-Handler aus dem übergeordneten Elemente entfernen und es ausdrückte, wo genau Sie es (ich denke, Sie wollen es auf +) sein wollen.

Verwandte Themen