У меня есть главное навигационное меню моего приложения в качестве компонента реакции, подключенного к хранилищу резервов с помощью Connect.Компонент меню также структурирован по разделам, а внутри разделов есть темы.Меню имеет переменные состояния (в магазине), которые указывают, должно ли меню казаться свернутым или нет.Я изменяю статус соответствующим действием и вижу, что внешний вид меню меняется, но внешний вид разделов не меняется.Я передаю значение коллапса как опору, но если не вызывает функцию рендеринга разделов меню, которые будут отрисованы соответственно.
Вот код компонентов Menu и MenuSection:
Menus.jsx
// modules/menu/components/Menu.jsx
import React from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as actions from '../actions'
import { MODULE_NAME } from '../constants'
import MenuSection from './MenuSection'
const propTypes = {
menu: PropTypes.shape({
sections: PropTypes.array,
collapsed: PropTypes.bool,
activeSection: PropTypes.number,
inflatedSection: PropTypes.number,
activeTopic: PropTypes.number,
}).isRequired,
actions: PropTypes.shape({
toggle: PropTypes.func,
activateSection: PropTypes.func,
toggleSection: PropTypes.func,
}).isRequired,
}
class Menu extends React.Component {
constructor(props) {
super(props)
}
toggleMenu = () => this.props.actions.toggleMenu()
activateSection = (s, t) => this.props.actions.activateSection(s, t)
toggleSection = (s) => this.props.actions.toggleSection(s)
render() {
const collapsed = this.props.menu.collapsed
const sections = this.props.menu.sections.map((section, i) => {
const {
disabled = false,
icon, text,
route = { to: '#' },
topics = [],
} = section
const active = this.props.menu.activeSection === i
const inflated = this.props.menu.inflatedSection === i
return (
<MenuSection
key={i}
idx={i}
to={route.to}
{...{
icon,
text,
topics,
disabled,
active,
inflated,
}}
activate={this.activateSection}
toggle={this.toggleSection}
activeTopic={this.props.menu.activeTopic}
collapsed={collapsed}
/>
)
})
const classes = classNames('menu', { collapsed: collapsed })
const size = collapsed ? 'small' : 'big'
return (
<nav className={classes}>
<img src={`${process.env.PUBLIC_URL}/imgs/logo-${size}.png`} />
<ul>
{sections}
</ul>
</nav>
)
}
}
Menu.propTypes = propTypes
const mapStateToProps = state => ({ [MODULE_NAME]: state.menu })
const mapDispatchToProps = dispatch => (
{ actions: bindActionCreators(actions, dispatch) }
)
export default connect(mapStateToProps, mapDispatchToProps)(Menu)
MenuSection.jsx
// modules/menu/components/MenuSection.jsx
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { NavLink, withRouter } from 'react-router-dom'
import classNames from 'classnames'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCaretDown, faCaretUp } from '@fortawesome/free-solid-svg-icons'
import MenuTopic from './MenuTopic'
const propTypes = {
idx: PropTypes.number.isRequired,
to: PropTypes.oneOfType([PropTypes.func, PropTypes.string]).isRequired,
icon: PropTypes.object.isRequired,
text: PropTypes.string.isRequired,
topics: PropTypes.arrayOf(PropTypes.object).isRequired,
activate: PropTypes.func.isRequired,
toggle: PropTypes.func.isRequired,
disabled: PropTypes.bool.isRequired,
active: PropTypes.bool.isRequired,
inflated: PropTypes.bool.isRequired,
activeTopic: PropTypes.number.isRequired,
collapsed: PropTypes.bool.isRequired
}
class MenuSection extends Component {
constructor(props) {
super(props)
this.onClick = this.onClick.bind(this)
this.activate = this.activate.bind(this)
}
shouldComponentUpdate(nextProps) {
const { active, inflated, activeTopic } = nextProps;
return (this.props.active !== active)
|| (this.props.inflated !== inflated) || (this.props.activeTopic !== activeTopic)
}
onClick() {
if (this.props.topics.length > 0) {
this.props.toggle(this.props.idx)
} else {
this.props.activate(this.props.idx, this.props.activeTopic)
}
}
activate(t) {
this.props.activate(this.props.idx, t)
}
render() {
const { idx, to, icon, text, topics, disabled, active, inflated, activeTopic, collapsed } = this.props
const items = (inflated ?
topics.map((topic, i) => (
<MenuTopic key={i} idx={i}
to={topic.route.to} text={topic.text} onClick={this.activate}
active={active && (activeTopic === i)} section={idx} />))
: []);
const classes = classNames({ disabled, active, inflated })
return (
<li className={classes}>
<NavLink to={to} activeClassName="active" onClick={this.onClick}>
<FontAwesomeIcon icon={icon} pull="left"/>
{!collapsed &&
<React.Fragment>
{' '}
{text}
{topics.length > 0 &&
<FontAwesomeIcon icon={ inflated ? faCaretUp : faCaretDown } pull="right" />
}
</React.Fragment>
}
</NavLink>
{(!collapsed) && inflated &&
<ul>
{items}
</ul>
}
</li>)
}
}
MenuSection.propTypes = propTypes
export default withRouter(MenuSection)
Есть идеи о том, что происходит?Я немного новичок в приложениях с реакцией-редуксом, так что, может быть, я что-то упустил.
Заранее спасибо!