简体   繁体   English

React-Redux组件不反映Redux Store中的更改

[英]React-Redux component does not reflect changes in Redux Store

I am new to Redux and i've been having a hard time rendering changes made to the store. 我是Redux的新手,我一直很难呈现对商店所做的更改。 I've been using Redux-DevTools to explore state changes and here is my problem. 我一直在使用Redux-DevTools探索状态变化,这是我的问题。

I have a sidebar which has expanded state as true/false. 我有一个侧边栏,其状态已扩展为true / false。 Initial state is below. 初始状态如下。

{expanded: false}

During the toggle action i trigger store.dispatch to change the state to true. 在切换动作期间,我触发store.dispatch将状态更改为true。 In React-DevTools i could see that my state is being changed, the console also logs the change when executed from within my sidenav component. 在React-DevTools中,我可以看到我的状态正在更改,当从我的sidenav组件中执行时,控制台也会记录更改。

I have a home page which is able to fetch the initial state of the store, however the actions from sidenav which updates the store doesn't re-render(props val dint change) the home page. 我有一个主页,该主页能够获取商店的初始状态,但是,从sidenav更新商店的操作不会重新呈现该主页。

I strongly feel the issue is related to this SO post but not able to get around the wrapped component concept. 我强烈认为问题与该SO帖子有关,但无法绕开包装的组件概念。 Any advice. 任何建议。

React Redux - changes aren't reflected in component React Redux-更改未反映在组件中

Below is code. 下面是代码。

编辑p52155my9j

Redux Store Redux商店

const rootReducer = combineReducers({
    sideBarReducerMain: sidebarReducer })

export const configurestore = () => {
    const store = createStore(rootReducer, composeWithDevTools(
      ));

    return store; }

Action generators 动作发生器

export const onExpand = {
    type: 'EXPAND',
    payload: {
        expanded: true
    }
}

export const onCollapse = {
    type: 'COLLAPSE',
    payload: {
        expanded: false
    }
}

Reducer 减速器

export const sidebarReducer = (state = {expanded:false},action) => {
 switch (action.type) {
     case 'EXPAND':
        return Object.assign({}, state, {expanded: true})
     case 'COLLAPSE':
        return Object.assign({}, state, {expanded: false})
    default:
        return state;   
 }
}

SideBar Toggle (The console logs the new state on every toggle) 侧边栏切换(控制台在每次切换时记录新状态)

onToggle = (expanded) => {

    expanded ? store.dispatch(onExpand):store.dispatch(onCollapse)
    this.setState({ expanded: expanded });

    //outputs the state change looks fine.
    console.log("State of store :: " + store.getState());

};

Home page 主页

import React from 'react';
import styled from 'styled-components'
import Main from './MainAlign'
import { connect } from 'react-redux'

class HomePage extends React.Component {


 getExpansionState() {
  console.log("From render" + this.props.expandedState)
    return this.props.expandedState
 }

 componentWillReceiveProps(nextProps) {
  console.log("Looks like this never gets called :( " + this.props.expandedState)
}


  render(props) {

      return (
        <div>
        <Main expanded={this.getExpansionState()}>
        <h1>Welcome</h1>
        <p>This is my site. Take a look around!</p>
        </Main>  
        </div>
      )


  }

}

const mapStateToProps = state => {
  console.log("New state " + state.expanded)
  return {
    expandedState: state.expanded
  }
}

export default connect(mapStateToProps)(HomePage);

REDUX DevTools REDUX开发工具

ReduxDevTools

You need to declare action creators (functions) which return actions (objects): 您需要声明返回操作(对象)的操作创建者 (函数):

export const onExpand = () => ({
  type: "EXPAND",
  payload: {
    expanded: true
  }
});

Then instead of calling store.dispatch , you should connect the action creator: 然后,而不是调用store.dispatch ,应该连接操作创建者:

withRouter(connect(null, { onExpand, onCollapse })(SideBar))

And invoke it in your component: 并在您的组件中调用它:

if (expanded) {
  this.props.onExpand();
} else {
  this.props.onCollapse();
}

Working code: 工作代码:

编辑xj64o1j0kw

Misc 杂项

this.setState({ expanded: expanded });
console.log("FROM SIDENAV" + this.state.expanded);

setState is asynchronous so you need use the callback to access the updated value: setState是异步的,因此您需要使用回调来访问更新的值:

this.setState({ expanded }, () => console.log("FROM SIDENAV" + this.state.expanded));

Also, there's no need to replicate the redux state in local component (single source of truth). 同样,也无需在本地组件(单个事实来源)中复制redux状态。

You can also combine onExpand and onCollapse into a single onToggle function and perform the toggle in reducer: expanded: !state.expanded , or pass the expanded flag as payload. 您还可以将onExpandonCollapse合并为一个onToggle函数,并在reducer中执行以下切换expanded: !state.expanded ,或将expanded标志作为有效载荷传递。

Change your mapStateToProps function like that: 像这样更改mapStateToProps函数:

const mapStateToProps = state => {
  console.log("New state " + state.expanded)
  return {
    expandedState: state.sideBarReducerMain.expanded
  }
}

You have a sideBarReducerMain state in your root,global state. 您的root(全局)状态中有sideBarReducerMain状态。 This sideBarRecuerMain state has an expanded value not the global one. sideBarRecuerMain状态的扩展值不是全局值。

Also, you don't need a payload for your action creators since you don't use them. 而且,您不需要动作创建者的有效载荷,因为您不使用它们。 Just a type is enough for your logic. 只需一种类型就足以满足您的逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM