我是React和Redux的新手,并且正在构建我的第一个Web应用程序。我正在构建的应用程序具有一个边栏,该边栏是使用Material UI Drawer创建的。它是通过侧边栏组件中包含的按钮触发的,但我不希望那样,我要做的是使按钮位于不同的组件中,并且drawer
的状态由Redux
处理
由于我是新手,所以我希望有人可以帮助我。这是我的代码。
我还没有将商店连接到我的组件,因为我不清楚 根据我的要求执行此操作的最佳方法
src / components / Sidebar.js
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from "react-router-dom";
import { withStyles } from '@material-ui/core/styles';
import Drawer from '@material-ui/core/Drawer';
import Button from '@material-ui/core/Button';
import List from '@material-ui/core/List';
import Divider from '@material-ui/core/Divider';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import MailIcon from '@material-ui/icons/Mail';
const styles = {
list: {
width: 250,
},
fullList: {
width: 'auto'
},
};
class Sidebar extends React.Component {
state = {
show: false,
};
toggleDrawer = (side, open) => () => {
this.setState({
[side]: open,
});
};
render() {
const { classes } = this.props;
const sideList = (
<div className={classes.list}>
<List>
<ListItem button component={Link} to="/">
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Home" />
</ListItem>
</List>
<Divider />
<List>
{['All mail', 'Trash', 'Spam'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
</div>
);
return (
<div>
<Drawer open={this.state.show} onClose={this.toggleDrawer('show', false)}>
<div
tabIndex={0}
role="button"
onClick={this.toggleDrawer('show', false)}
onKeyDown={this.toggleDrawer('show', false)}
>
{sideList}
</div>
</Drawer>
</div>
);
}
}
Sidebar.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(Sidebar);
如您所见,drawer
有一个名为state
的{{1}},最初设置为show
。在上面的代码中,false
存储在本地,但是我不确定使用Redux是否正确。
这是我想在其中使用按钮的state
,它可能不是一直都在这里,但出于这个问题,我们假设它在这里。
src / components / Layout.js
layout
我认识到此按钮在上面的代码中不起作用,因为它无法访问toggleDrawer中的状态。
src / store / configureStore.js
import React from 'react';
import { Container } from 'reactstrap';
import PropTypes from 'prop-types';
import Sidebar from './Sidebar';
export default props => (
<div className="beta">
<Sidebar />
<Button onClick={this.toggleDrawer('show', true)}>Open</Button>
<div className="container-fluid">
{props.children}
</div>
</div>
);
Container.propTypes = {
fluid: PropTypes.bool
}
src / store / Stage.js
import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
import thunk from 'redux-thunk';
import { routerReducer, routerMiddleware } from 'react-router-redux';
import * as Stage from './Stage';
export default function configureStore(history, initialState) {
const reducers = {
sidebar: Stage.reducer
};
const middleware = [
thunk,
routerMiddleware(history)
];
// In development, use the browser's Redux dev tools extension if installed
const enhancers = [];
const isDevelopment = process.env.NODE_ENV === 'development';
if (isDevelopment && typeof window !== 'undefined' && window.devToolsExtension) {
enhancers.push(window.devToolsExtension());
}
const rootReducer = combineReducers({
...reducers,
routing: routerReducer
});
return createStore(
rootReducer,
initialState,
compose(applyMiddleware(...middleware), ...enhancers)
);
}
以上是我相当粗鲁的尝试,以编写一个动作和一个reducer,使其能够将true或false传递到侧边栏并打开它。我需要帮助,当我单击布局中的菜单按钮时,如何(简单地)告诉redux更改边栏的状态?
感谢您的帮助和指导。
答案 0 :(得分:0)
首先,我建议您更换
if (action.type === sidebarOpen) {
someaction..
} else {
someaction..
}
与
switch(action.type)
{
case XXX: someaction; break;
case YYY: someaction; break;
default: somedefaultaction; break;
}
在 src / store / Stage.js 中,当reducer足够长时,它将更具可读性。
现在,关于您的担忧,当前实现中缺少的步骤是状态/属性与化简器的映射。
看看下面的代码:
const mapStateToProps = state => ({
myVar: state.myVarFromReducer,
});
const mapDispatchToProps = dispatch => ({
expandFn: () => expand(dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(myComponent);
让我们忽略mapDispatchToProps
,它将不会引起我们的关注。
我邀请您参观https://react-redux.js.org/using-react-redux/connect-mapstate和https://react-redux.js.org/using-react-redux/connect-mapdispatch,以更好地了解redux和react之间的联系。
NB:此代码示例通常出现在组件文件的末尾。
我们在这里拥有的是指定状态与我的组件的绑定connect(mapStateToProps,..)(myComponent)
。
例如,指定状态是您在 src / store / Stage.js 中定义的值。
因此,根据您的情况,您必须在商店中connect
使用组件,其操作完全如上所述。
然后,您必须映射要在组件状态中具有的化简器状态的信息。
看起来像这样:
const mapStateToProps = state => ({
show: state.show,
});
基本上,这意味着“将组件状态的属性show
与化简器的属性show
绑定”。
如果reducer的show
属性发生更改,则将通知该组件,并更新其show
属性。