2017-09-07 4 views
1

Ich lerne React Redux seit den letzten Tagen. Ich habe eine kleine App gebaut. Ich versuche, Daten mit aktualisierten Likes für das Nachrichtenobjekt an die API zurückzusenden.Aktion empfängt vorherigen lokalen Status in React Redux-App

Hier ist ein Code für die News Item Component.

import React, { Component} from 'react'; 
import { connect } from 'react-redux' 
import { bindActionCreators } from 'redux'; 
import { updateArticleLikes } from '../../actions/updateNews'; 

class NewsItem extends Component { 
    constructor(){ 
    super() 

    this.state = { 
     likes: 0, 
     key: '' 
    } 
    } 

    componentDidMount(){ 
    this.setState({ 
     likes: this.props.item.likes, 
     key: this.props.item.key 
    }) 
    } 

    increaseCount = event => { 
    this.newState(event); 
    } 

    newState = (event) => { 
    console.log(this.state) 
    this.setState({ 
     likes: this.props.item.likes + 1, 
     key: this.props.item.key 
    }, this.submitUpdate(event)) 
    } 

    submitUpdate = (event) => { 
    event.preventDefault(); 
    // console.log(this.state) 

    this.props.updateArticleLikes(this.state) 
    this.setState({likes: 0, key: ''}) 
    } 

    render(){ 
    const {item } = this.props 
    return(
     <div key={item.key} > 
     <h4> - <a href={item.url} target="_blank" rel="noopener noreferrer">{item.title} </a></h4> 
     <button onClick ={ this.increaseCount } data-likes={item.likes} value={item.key}>Like { this.state.likes }</button> 
     </div> 
    ) 
    } 
} 

const mapDispatchToProps = dispatch => { 
    return bindActionCreators(
    { updateArticleLikes }, dispatch); 
}; 


export default connect(null, mapDispatchToProps)(NewsItem); 

Und hier ist Code für die Aktion updateArticleLikes.

Das Problem ist aus irgendeinem Grund, Funktion updateArticleLikes empfängt den vorherigen Zustand. Ich bin mir sicher, dass die newState-Funktion den lokalen Status aktualisiert, da ich den Wert im DOM im Button-Tag ({this.state.like}) sehen kann, aber ich verstehe nicht, warum die Aktion den vorherigen Status erhält.

Ich dachte an mapStateToProps, aber es wird in diesem Fall nicht funktionieren, da ich mich mit dem lokalen Zustand befasse. Kann es seit zwei Tagen nicht mehr machen! Irgendein Vorschlag?

Die Lösung, die funktioniert:

Oblosys hat mir geholfen, dieses Problem zu lösen. Nach dem Entfernen des Arguments von der Funktion submitUpdate und dem Entfernen von seState und preventDefault funktioniert meine Funktion jetzt sehr gut. Es aktualisiert und zeigt den korrekten Status an und sendet auch richtige Daten an den Server. Hier ist mein geänderter Code für alle, die das gleiche Problem haben.

newState = (event) => { 
    console.log(this.state) 
    event.persist() 
    this.setState({ 
     likes: this.props.item.likes + 1, 
     key: this.props.item.key 
    }, this.submitUpdate) 
    } 

    submitUpdate =() => { 
    this.props.updateArticleLikes(this.state) 
    } 

Antwort

1

Als this.submitUpdate(event) ist ein Parameter von this.setState, ausgewertet wird, bevor setState auch genannt wird, statt, wenn der Zustand aktualisiert wird. Sie können dies verhindern, indem Sie es in einen Thunk verwandeln: () => this.submitUpdate(event).

Beachten Sie, dass Sie auch eine event.persist() zu tun haben, wenn Sie das Ereignis in der setState Rückruf verwenden möchten (oder bevorzugt behandeln nur die preventDefault davor und es überhaupt nicht passieren, da preventDefault Aufruf auf Ereignisse beharrte ist ein bisschen zwielichtig.)

+0

Vielen Dank, Oblosys. Ich verstehe Ihren Punkt, dass submitUpdate ausgewertet wird, noch bevor setState aufgerufen wird. Aber es fällt mir schwer, deine Aussage zu verstehen. "Ich kann das verhindern, indem ich sie in einen Thunk verwandle:() => this.submitUpdate (Ereignis)." Würde es dir etwas ausmachen, mir ein bisschen darüber zu erklären? –

+0

Das Callback-Argument 'setState' sollte eine Funktion sein, aber Sie übergeben einen Wert (dh das Ergebnis des Aufrufs von' this.submitUpdate' mit dem Argument 'event', wobei'undefined' ist). Umwickeln Sie den Aufruf in eine anonyme Funktion mit Keine Argumente (der Thunk), Sie werden die Ausführung verzögern, bis der Callback tatsächlich aufgerufen wird (nachdem der Status aktualisiert wurde.) – Oblosys

+0

Vielen Dank, Oblosys, Sie haben mich in die richtige Richtung geschoben. Es sendet jetzt korrekte Daten. Mein bearbeiteter Code ist in der Frage, ob jemand anderes das gleiche Problem hat. –

Verwandte Themen