在哪里保持状态

时间:2017-12-14 09:57:03

标签: javascript reactjs redux react-redux

我有一个下拉菜单,点击该菜单可切换下拉菜单的可见性。在此下拉列表中,我想创建可折叠标题,以便在您单击它们时切换子项的可见性。我不确定在哪里为这些标头保持打开状态。

我有两个减速器,一个模块减速器和一个导航减速器。在导航减速器中,我保持导航打开/关闭状态,在模块中我保留模块。这些是从API获取的。这些模块在整个系统中使用,但也用于导航,因为它们组成了多个导航项。

我是否从API中将已打开的属性附加到已返回的模块并切换这些属性?我是否将 OpenNavigationIndex 添加到导航状态并使用选择器组合模块和开放索引?

我在这里设置了一个示例https://codesandbox.io/s/kwz6m42v1r

所以我的问题是,我在哪里保持仅由导航使用的模块的打开/关闭状态?

index.js

import React from 'react';
import { render } from 'react-dom';

import { createStore } from 'redux';
import { reducer } from './reducer';

import { Provider } from 'react-redux';

const store = createStore(reducer);


import Navigation from './Navigation';
import Modules from './Modules';

const App = () => (
  <Provider store={store}>
  <div>
    <Navigation />
    <Modules />
  </div>
  </Provider>
);

render(<App />, document.getElementById('root'));

reducer.js

import { combineReducers } from 'redux';

const navigationReducer = (state = { open: false }, action) => {

  switch(action.type) {
    case "TOGGLE_NAVIGATION": {
      return {
        ...state,
        open: !state.open
      }
    }
    default: {
      return state;
    }
    }
}

const modulesReducer = (state = [], action) => {

  switch(action.type) {

    case "FETCH_MODULES": {
      return [{ name: "Module 1", children: [ "child 1", "child 2"]},
        { name: "Module 2", children: ["child 1", "child 2"] },
        { name: "Module 3", children: ["child 1", "child 2"] }]
      }
    default: {
      return state;
    }
    }

  }

export const reducer = combineReducers({
  navigation: navigationReducer,
  modules: modulesReducer
})

navigation.js

import React from 'react';
import { connect } from  'react-redux';


class Navigation extends React.Component {

  renderModules = (modules) => {

    return this.props.modules.map(module =>
      <div>{module.name}
        <div>{module.children.map(child => <div>{child}</div>)}</div>
      </div>)

  }

  render() {

    return (
      <div style={{ backgroundColor: 'green' }}>
        <button onClick={ this.props.toggleNavigation }>Toggle navigation</button>
        { this.props.open && this.renderModules(this.props.modules)}
      </div>
    )
  }
}

const mapStateToProps = state => ({
  modules: state.modules,
  open: state.navigation.open
});

const mapDispatchToProps = dispatch => ({
  toggleNavigation: () => dispatch({ type: 'TOGGLE_NAVIGATION'})
});

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

modules.js

import React from 'react';
import { connect } from 'react-redux';


class Modules extends React.Component {

  componentDidMount() {
    this.props.fetch();
  }

  renderModules = (modules) => {

    return this.props.modules.map(module =>
        <div>{module.name}
          <div>{module.children.map(child => <div>{child}</div>)}</div>
        </div>)

  }
  render() {

    if (!this.props.modules) {
      return <div>No modules</div>
    }

    return (
      <div>
       {this.renderModules(this.props.modules)}
      </div>
    )
  }
}

const mapStateToProps = state => ({
  modules: state.modules,
});

const mapDispatchToProps = dispatch => ({
  fetch: () => dispatch({ type: 'FETCH_MODULES' })
});

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

1 个答案:

答案 0 :(得分:0)

如果您想存储仅与该组件相关的内容的状态,我建议您在构造函数中使用react状态(this.state,并在需要时使用this.setState修改它)而不是属性/道具(redux商店)。如果你需要许多组件需要知道的东西,那么你可能想要使用道具。

我建议你阅读以下文章:

https://spin.atomicobject.com/2017/06/07/react-state-vs-redux-state/

作为一个例子,我通常使用redux store;但是对于跟踪输入数据的事情,我使用状态,因为该信息与其他组件无关。

在你的例子中,我使用反应状态进行&#34;导航打开&#34;状态,因为它更简单,并将完美地工作。对于模块,您确实需要使用属性。

修改:此链接也很有用。 https://reactjs.org/docs/faq-state.html

编辑2 :更新了您的代码。 https://codesandbox.io/s/714yw0r19x