React Redux:获取道具和更新状态

时间:2017-11-04 20:19:58

标签: javascript reactjs redux

我第一次尝试使用React / Redux / JS。我对组件中的状态设置与让redux更新它有点困惑。

我想单击一个按钮将lightOn设置为true,并显示更新的this.props.lightOn值。我遗漏了一些根本但不确定的东西。

动作:

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

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

在组件中,{this.props.onLight}未定义,因此我没有正确更新状态:

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

reducer(用spread运算符更新):

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

5 个答案:

答案 0 :(得分: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时,你可以通过返回一个新状态来实现这一点

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

答案 1 :(得分:2)

它是如何工作的? 通过connect,您可以注入用于控制redux状态并将其绑定到组件的props。例如:

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

在给定的示例中,您将someReduxState状态的一部分绑定到stateProp,它被注入到组件中。您正在注入将在redux中调度和操作的方法(sendSomething)。如果组件在显示redux状态的一部分时继续,则每次redux状态更改时都会更新,因为注入组件的props会发生变化。您可以在官方Redux文档here中找到更多信息,或者您可以在egghead here上观看免费教程。

答案 2 :(得分:1)

你没有在这里返回一个新州

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

您直接返回action.payload,这只是lightStatus

这意味着您无法访问state.lightOn

中的mapStateToProps

你应该做的

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

或直接

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

这样整个状态不会丢失,也不会直接改变状态。 在这里,为了简单起见,我使用的是object spread operator而不是Object.assign

答案 3 :(得分:1)

reducer上的错误,reducer应该使用lightOn键返回状态对象,但是返回有效负载值,这就是问题所在。 你的reducer应该像这样返回带有效负载值的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;
  }
}

答案 4 :(得分:0)

我没有使用数组设置状态,而是使用object设置。我想我将lightOn对象放在光阵列中,这使得它无法访问。

动作:

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Local $Day, $Week, $Month ; we have to declare the variables for our Example1() function BEFORE we use them
Example1($Day, $Week, $Month) ; we here call our function with the previously declared variables as parameter.
; The function will then fill in the data into our variables before we use them to set the radio text

GUICreate("Example", 143, 103, 192, 124)
GUISetFont(12, 400, 0, "Open Sans")
$Radio1 = GUICtrlCreateRadio($Day, 24, 16, 113, 17) ; set the data for the three controls
$Radio2 = GUICtrlCreateRadio($Week, 24, 40, 113, 17)
$Radio3 = GUICtrlCreateRadio($Month, 24, 64, 113, 17)
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func Example1(ByRef $Day, ByRef $Week, ByRef $Month) ; NOTE: ByRef means that the given variables will be OVERWRITTEN, that also means that the variables MUST EXIST before the function is called
    $LimitTime =  _DateDiff('s', "1970/01/01 00:00:00", _NowCalc()) ; Get the current time (convert to seconds)
    $Day = 86400
    $Week = 604800
    $Month = 2592000
EndFunc

减速器:

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