Я новичок в React и Redux и работаю над созданием своего первого веб-приложения.У приложения, которое я создаю, есть боковая панель, которую я создал с помощью 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
, называемый show
, который изначально установлен на false
.В приведенном выше коде state
хранится локально, но я не уверен, что это правильно для использования Redux.
Вот мой layout
, где я бы хотел, чтобы кнопка жила, она может не бытьздесь все время, но ради этого вопроса допустим, что он живет здесь.
src / components / Layout.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
}
Я понимаю, что эта кнопкане будет работать в приведенном выше коде, потому что он не может получить доступ к состоянию в toggleDrawer.
src / store / configureStore.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)
);
}
src / store / Stage.js
const sidebarOpen = 'SIDEBAR_OPEN';
const initialState = { show: false }
export const actionCreators = {
open: () => ({
type: sidebarOpen
})
};
export const reducer = (state, action) => {
state = state || initialState;
console.log("Initial State");
console.log(state)
if (action.type === sidebarOpen) {
return {
...state,
show: state.show = true
};
} else {
return {
...state,
show: state.show = false
}
}
return state;
};
Вышесказанное - моя довольно грубая попытка написать действие и редуктор, которые могли бы передать значение true или false на боковую панель и открыть ее.Мне нужна помощь, как я могу (просто) сказать, чтобы redux изменил состояние моей боковой панели при нажатии кнопки меню, которая находится в моем макете?
Любая помощь и руководство приветствуются.