反应 |使用创建选择器传递 Redux 状态并隐藏菜单项

React | Pass Redux state with create selector and hide menu item

在处理边栏的 React 组件中,我们有 Menu Items,如 modules。我想从 Redux 传递一个特定的状态,并且在 false 的情况下隐藏一个特定的项目。 我做到了,但是使用 componentWillRecieveProps 将状态作为 Props 传递。但我需要专门用 reselect 中的 createSelector 来做,因为 componentWillRecieveProps 将被弃用,我们开始越来越多地使用 reselect。

问题是我不知道该怎么做。重新选择文档比帮助更令人困惑。 所以你能帮点忙吗?

分量:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { createSelector } from 'reselect';

import { isRouteActive } from './location';

class ModuleNavigation extends Component {
  static propTypes = {
    modules: PropTypes.array,
    user: PropTypes.object,
    currentRoute: PropTypes.string,
    isMinimized: PropTypes.bool,
    isItAvailable: PropTypes.bool,
  }

  state = {
    isOpen: false,
  }

  constructor(props) {
    super(props);

    this.topNavRef = React.createRef();
    this.bottomNavRef = React.createRef();
    this.moduleNavRef = React.createRef();
  }

  componentDidUpdate() {
    this.updateArrows();
  }

  componentDidMount() {
    this.updateArrows();
    window.addEventListener('resize', this.updateArrows);
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.updateArrows);
  }

  onToggle = () => {
    this.setState({ isOpen: !this.state.isOpen });
  }

  getRefId = (index) => {
    if (index === 0) return this.topNavRef;
    if (this.props.modules && index === this.props.modules.length - 1) return this.bottomNavRef;

    return null;
  }

  renderGroup = (group, index, user, currentRoute, isMinimized) => (
    <ul ref={this.getRefId(index)} key={group.name} className="module-navigation-group nav">
      {
        <li className={classNames('mt-10 mb-10 module-navigation-group-separator', { hidden: index === 0 })} />
      }
      {group.children
        .filter(mod =>
          mod.route && (!mod.permissions || userHasPermission(user, mod.permissions)))
        .map(mod =>
          (<li key={mod.name} className={classNames('module-navigation-group-item', { active: isRouteActive(currentRoute, mod.route) })}>
            <a href={(mod.parentApp ? '#' : '') + mod.route} target={mod.target} title={mod.name}>
              <i className={`fa ${mod.classNames} module-navigation-group-item-icon`} />
              {!isMinimized && <span className="hidden-xs hidden-sm ml-15 module-navigation-group-item-label">{mod.name}</span>}
            </a>
          </li>))}
    </ul>
  )

  render() {
    const {
      modules,
      currentRoute,
      user,
      isItAvailable,
    } = this.props;

    if (!user || !modules || !modules.length) return null;

    return (
      <div className={classNames('module-navigation-wrapper', { 'is-minimized': isMinimized })}>
        <div ref={this.moduleNavRef} isZKAvailable={isZKAvailable} className="module-navigation">
          {
            modules.map((group, index) =>
              this.renderGroup(group, index, user, currentRoute, isMinimized))
          }
        </div>
    );
  }
}

export default ModuleNavigation;

我想在此处将布尔值 isItAvailable 传递给名为 modules 的菜单项,并检查模块的子项以查找特定的模块。如果isItAvaialable =false不显示

您好,您需要对 class 组件进行小规模重构,以便您可以使用 connect hoc 包装组件并获取 state 值并将它们作为 props.

在您的 class 组件中进行这些更改,以便获得 isAvailable 作为道具,例如this.props.isAvailable:

// import connect hoc from react-redux
import { connect } from 'react-redux'

// import your selector from e.g. selectors.js, on the top
import {getIsAvailable} from './selectors'


// bottom, out of the class create the mapStateToProps function,
// in order to get state values and inject them as props to the component
const mapStateToProps = (state) => {
  return {
    isAvailable: getIsAvailable(state),
  }
}

// you export your component wrapped with the connect hoc, like so
export default connect(mapStateToProps, null)(ModuleNavigation)

在您的选择器文件中,您导入 reselect 并像这样使用 CreateSelecto

import { createSelector } from 'reselect'

// get the local state data.
// you are gonna change the structure based on yours
const getLocalState = state => state.data

// here with creteSelector:
// 1. call the localstate and return the data
// 2. get the data as param of an arrow func and 
// make whatever we like with the data (calcs, checks etc)
// and finally return the data we need.
export const getIsAvailable = createSelector(
  getLocalState,
  data => data.isAvailable || false
)

就是这样。希望对你有帮助。