2017-09-07 4 views
1

私はここ数日からReact Reduxを学習しています。私は小さなアプリケーションを構築しています。私はニュースオブジェクトの更新された好きなものでAPIにデータを送り返そうとしています。アクションはReact Reduxアプリで以前のローカル州を受け取っています

ここにニュースアイテムコンポーネントのコードがあります。

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

ここでは、updateArticleLikesアクションのコードを示します。

import { API_URL } from '../global'; 

    export function updateArticleLikes(data) { 
     // here, it shows old state in data 
    console.log(data) 
     return dispatch => { 
     console.log(JSON.stringify({"article": data})) 
     return fetch(API_URL + '/newsupdate', { 
      method: 'PATCH', 
      headers: { 
      'Accept': 'application/json', 
      'Content-Type': 'application/json' 
      }, 
      body: JSON.stringify({"article": data}) 
     }) 
     } 
    } 

問題は何らかの理由で、関数updateArticleLikesが以前の状態を受信して​​います。私はボタンのタグ({this.state.like})のDOMの値を見ることができるので、newState関数はローカル状態を更新していると確信していますが、なぜアクションが以前の状態を受け取っているのかわかりません。

私はmapStateToPropsを考えましたが、私はローカルステートを扱っているので、この場合は動作しません。過去2日から動作させることはできません!なにか提案を?

勤務ソリューション:

Oblosysは、この問題を解決するために私を助けました。 submitUpdate関数から引き数を取り除いた後、seStateとpreventDefault my関数を削除した後は、すごくうまくいきます。これは、正しい状態を更新して表示し、サーバーに正しいデータを送信しています。ここでは、同じ問題を抱えている人のために私の変更されたコードです。 this.submitUpdate(event)として

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) 
    } 

答えて

1

this.setStateのパラメータであるsetStateがさえ呼ばれる前に、それが代わりに状態が更新されたときの、評価されます。あなたはそれをサンクに変えることでこれを防ぐことができます:() => this.submitUpdate(event)。あなたが好ましく、ちょうどすべてでそれを渡すその前preventDefaultを処理していない、setStateコールバックでイベントを使用(またはしたい場合は、イベントを永続化にpreventDefaultを呼び出しているので、event.persist()を行う必要があるでしょう

注意少しばかげています。)

+0

ありがとう、Oblosys。私は、setStateが呼び出される前でもsubmitUpdateが評価されているというあなたの点を理解しています。しかし、私はあなたの声明を理解するのに苦労しています。「私はこれをサンクに変えることでこれを防ぐことができます:()=> this.submitUpdate(イベント)」あなたは私にそれについて少し説明してもらえますか? –

+0

'setState'のコールバック引数は関数でなければなりませんが、値を渡しているはずです(つまり' event.sub'を引数とする 'this.submitUpdate'を呼び出した結果は' undefined'です)。引数なし(サンク)、コールバックが実際に呼び出されるまで(状態が更新された後)実行を延期します。 – Oblosys

+0

ありがとう、Oblosys、あなたは正しい方向に私を押しました。今すぐ正しいデータを送信します。他の誰かが同じ問題を抱えているのであれば、編集したコードは問題になります。 –

関連する問題