React Redux - changes aren't reflected in comp

2019-05-29 04:17发布

问题:

I created a simple React component for generating menu, and I wanted to replace it's visibility toggling with Redux (instead of state).

My component looks like this:

class SiteMenu extends React.Component {
  constructor(props) {
    super(props);
  }

  toggle(force = false) {
    let active = !active;

    store.dispatch({
      type: 'TOGGLE',
      active
    });
  }

  render() {
    const wrapperClass = this.props.active ? `${this.props.className}__wrapper ${this.props.className}__wrapper--active` : `${this.props.className}__wrapper`;
    return (
      <nav className={this.props.className} ref="nav">
        <button className={`${this.props.className}__trigger`} onClick={this.toggle.bind(this)}>
          {this.props.active}
        </button>
        <ul className={wrapperClass}>
        </ul>
      </nav>
    );
  }
}

I added mapStateToProps:

const mapStateToProps = (store) => {
  return {
    active: store.menuState.active
  }
};

and connect

connect(mapStateToProps)(SiteMenu);

My store:

import { createStore } from 'redux';
import reducers from './reducers/index.js';

const store = createStore(reducers, window.devToolsExtension && window.devToolsExtension());
export default store;

and reducers:

import { combineReducers } from 'redux';
import menuReducer from './menu-reducer';

const reducers = combineReducers({
  menuState: menuReducer
});

export default reducers;

const initialMenuState = {
  active: false
};

const menuReducer = (state = initialMenuState, action) => {
  switch(action.type) {
    case 'TOGGLE':
      console.log(action);
      return Object.assign({}, state, { active: action.active });
  }

  return state;
};

export default menuReducer;

When I check my Redux DevTools, state is changing. What should I do?

Code in the repo: https://github.com/tomekbuszewski/react-redux

回答1:

to use connect func , also you should add Provider from react-redux

render(<Provider store={store}><Parent /></Provider>, app);

then you should add wrapped component to Parent component

const SiteMenuWrapped = connect(mapStateToProps)(SiteMenu);

///in Parent component
<Header className="site-header">
      <SiteMenuWrapped 
        className="site-navigation"
        content={this.state.sections}
      />
</Header>


回答2:

Few issues:

  1. connect returns a higher order component, so best advice is to split out each component to a separate file and export the result of connect. See the examples at e.g. http://redux.js.org/docs/basics/ExampleTodoList.html. This means that your mapStateToProps function is never being called, hence why this.props.active is always undefined.
  2. Your store registration is incorrect, the second parameter to createStore is the initial state. To register the Chrome Redux dev tools see https://github.com/zalmoxisus/redux-devtools-extension
  3. You should use <Provider> to make the store available to all components. See the Redux docs.
  4. You can dispatch actions through this.props.dispatch or use mapDispatchToProps, see https://github.com/reactjs/react-redux/blob/master/docs/api.md