2017-11-04 24 views
3

私は初めてReact/Redux/JSを試しています。私はコンポーネントの状態を設定することについて少し混乱しています。React Redux:小道具の入手と状態の更新

ボタンをクリックしてlightOnをtrueに設定し、更新されたthis.props.lightOnの値を表示したいとします。私は基本的な何かを欠いているが、何が分からないのか。

アクション:

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
//import * as actions from '../actions'; 
import { setLight } from '../actions'; 
import { bindActionCreators } from 'redux'; 

class Light extends Component { 
    render() { 

    return (
     <div> 
     Light Status: {this.props.lightOn} 
     <button 
      className="btn" 
      onClick={() => this.props.setLight(true)} 
     > 
      Set Light! 
     </button> 
     </div> 
    ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
    lightOn: state.lightOn 
    }; 
} 

function mapDispatchToProps(dispatch) { 
    //whenever selectBook is called the result should be passed to all of our reducers 
    return bindActionCreators({ setLight: setLight }, dispatch); 
} 

export default connect(mapStateToProps, mapDispatchToProps)(Light); 

を(拡散演算子を使用して更新)減速:成分で

export const setLight = lightStatus => dispatch => { 
    const res = lightStatus; 
    console.log(res); // => true on click 

    dispatch({ type: SET_LIGHT, payload: res }); 
}; 

、{this.props.onLightは}私は正常状態を更新するわけではない未定義です。

import { SET_LIGHT } from '../actions/types'; 

export default function(state = [], action) { 
    switch (action.type) { 
    case SET_LIGHT: 
    return { ...state, lightOn: action.payload }; 
    default: 
     return state; 
    } 
} 

答えて

0

stateをarrayで設定する代わりに、objectで設定します。 lightOnオブジェクトをライト配列に入れていて、アクセス不可能にしていたと思います。

アクション:

export const setLight = lightStatus => dispatch => { 
    dispatch({ type: SET_LIGHT, payload: lightStatus }); 
}; 

減速:

import { SET_LIGHT } from '../actions/types'; 

export default function(state = { on: false }, action) { 
    console.log('state ', state); 
    switch (action.type) { 
    case SET_LIGHT: 
     return { ...state, on: action.payload }; 
    default: 
     return state; 
    } 
} 

コンポーネント:

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 
//import * as actions from '../actions'; 
import { setLight } from '../actions'; 
import { bindActionCreators } from 'redux'; 

class Light extends Component { 
    render() { 
    return (
     <div> 
     Light On: {this.props.light.on.toString()} 
     <button 
      className="btn" 
      onClick={() => this.props.setLight(!this.props.light.on)} 
     > 
      Set Light! 
     </button> 
     </div> 
    ); 
    } 
} 

function mapStateToProps(state) { 
    return { light: state.light }; 
} 

function mapDispatchToProps(dispatch) { 
    return bindActionCreators({ setLight: setLight }, dispatch); 
} 

export default connect(mapStateToProps, mapDispatchToProps)(Light); 
2

関数に直接渡すのではなく、状態として設定するのはどうですか?最初にConstructorの中にバインドしてから、setStateをtrueにクリックします。

constructor(props) { 
super(props); 
this.state:{lightOn: false}; 
this.OnClick = this.OnClick.bind(this); 
} 

onClick(event) { 
this.setState({lightOn: true}); 
} 

onClick ={this.onClick()} 

あなたはReduxのを使用しているとして、あなたはあなたがあなたをしている

ここ
export default function(state = [], action) { 
    switch (action.type) { 
    case SET_LIGHT: 
     return action.payload; 
    default: 
     return state; 
    } 
} 

を新しい状態を返すされていない代わりに

return {...state, action.payload }; 
+0

何?ヘックスはレフィックスを使用しています。 Hesはこれを処理する内部状態の方法を探していません... – WilomGfx

1

を新鮮な状態を返すことによって、このようにそれを行うことができます直接返すaction.payloadこれは簡単ですlightStatus

UはあなたがmapStateToProps

あなたが

case SET_LIGHT: 
       return { 
       ...state, 
       lightOn: action.payload, 
       }; 

、または直接

case SET_LIGHT: 
        return { 
        ...state, 
        action.payload, 
        }; 

全体の状態が失われていません。この方法で、その直接の状態を変異ではないがやるべきことでstate.lightOnにアクセスすることはできません。 ここで私はObject.assignの代わりにobject spread operatorを使用しています。

+0

私は私のレデューサーのように広がる演算子を追加しました:return {... state、lightOn:action.payload}しかし、私はまだこの値を取得していませんコンポーネント内の.props.lightOn –

1

減速機で間違っている、減速機はlightOnキーで状態オブジェクトを返す必要がありますが、ペイロード値を返す、これが問題です。 あなたのレデューサーは、このようなペイロード値でlightOnを返さなければなりません。

import { SET_LIGHT } from '../actions/types'; 

export default function(state = {}, action) { 
    switch (action.type) { 
    case SET_LIGHT: 
     return {...state, action.payload} 
    default: 
     return state; 
    } 
} 
2

どのように機能しますか? connectからredux状態を制御し、それをコンポーネントにバインドするために使用されるプロップを挿入できます。例えば:

class SomeComponent extends React.Component { 
    componentWillMount() { 
     this.props.sendSomething('someName'); 
    } 

    render() { 
     return (
      <div>{this.props.stateProp}</div> 
     ) 
    } 
} 

const mapStateToProps = state = ({ 
    stateProp: state.someReduxState, 
}); 

const mapDispatchToProps = dispatch => ({ 
    sendSomething: (name) => dispatch(someActionCreator(name)), 
}); 

const ConnectedComponent = connect(
    mapStateToProps, 
    mapDispatchToProps, 
)(SomeComponent); 

与えられた例では、コンポーネントの中に注入され、statePropの状態のsomeReduxState一部を結合しています。あなたは派遣するアクションメソッド(sendSomething)とreducexのアクションを注入しています。コンポーネントが還元状態の一部を表示している場合、コンポーネントに注入された小道具が変更されるため、還元状態が変化するたびに更新されます。公式のReduxのマニュアルhereにもっと見つけることができます。または、あなたはegghead hereに関する無料のチュートリアルを見ることができます。

関連する問題