簡體   English   中英

React Redux:獲取道具和更新狀態

[英]React Redux: Getting Props And Updating State

我是第一次嘗試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;
  }
}

如何將其設置為狀態而不是直接傳遞給函數? 首先將它綁定在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 };

這個怎么運作? 通過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文檔中的更多內容,或者您​​可以在此處觀看有關egghead的免費教程。

你沒有回到這里的新州

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.assign

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

我沒有使用數組設置狀態,而是使用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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM