Reactjs 如何更改React with Redux ASP.NET核心应用程序中侧栏的状态?
我对React和Redux都是新手,我正在构建我的第一个web应用程序。我正在构建的应用程序有一个侧栏,我是用它创建的。它是由边栏组件中包含的按钮触发的,但我不希望这样,我想做的是让按钮位于不同的组件中,并且Reactjs 如何更改React with Redux ASP.NET核心应用程序中侧栏的状态?,reactjs,asp.net-core,redux,Reactjs,Asp.net Core,Redux,我对React和Redux都是新手,我正在构建我的第一个web应用程序。我正在构建的应用程序有一个侧栏,我是用它创建的。它是由边栏组件中包含的按钮触发的,但我不希望这样,我想做的是让按钮位于不同的组件中,并且抽屉的状态由Redux处理 因为我是新手,我希望有人能帮我。这是我的密码 我还没有将我的商店连接到我的组件,因为我不清楚 考虑到我的要求,这是最好的方法 src/components/Sidebar.js import React from 'react'; import PropTypes
抽屉的状态由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);
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
}
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)
);
}
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;
};
我意识到这个按钮在上面的代码中不起作用,因为它无法访问toggleDrawer中的状态
src/store/configureStore.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);
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
}
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)
);
}
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;
};
src/store/Stage.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);
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
}
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)
);
}
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改变我的侧边栏的状态
感谢您的帮助和指导。首先,我建议您更换您的
if (action.type === sidebarOpen) {
someaction..
} else {
someaction..
}
与
在src/store/Stage.js中,当减速器增长足够大时,它将更具可读性
现在,关于您所关心的问题,您当前实现中缺少的步骤是使用reducer映射state/props
请查看以下代码:
const mapStateToProps = state => ({
myVar: state.myVarFromReducer,
});
const mapDispatchToProps = dispatch => ({
expandFn: () => expand(dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(myComponent);
让我们忽略mapDispatchToProps
,它不会用于我们的关注
我邀请您查看并更好地理解redux和react之间的联系
注意:此代码示例经常出现在组件文件的末尾
我们这里有一个绑定connect(mapStateToProps,…)(myComponent)
,它与我的组件处于指定状态。
例如,指定的状态是您在src/store/Stage.js中定义的值
因此,在您的情况下,您必须将您的组件与存储连接起来,具体操作方法如上所述。
然后,您必须映射要在组件状态中包含的减速器状态的信息。
它将如下所示:
const mapStateToProps = state => ({
show: state.show,
});
基本上,这意味着“将组件状态的属性show
与减速器的属性show
绑定”
如果减速器的show
属性发生变化,则会通知该部件,并更新其show
属性。首先,我建议您更换减速器
if (action.type === sidebarOpen) {
someaction..
} else {
someaction..
}
与
在src/store/Stage.js中,当减速器增长足够大时,它将更具可读性
现在,关于您所关心的问题,您当前实现中缺少的步骤是使用reducer映射state/props
请查看以下代码:
const mapStateToProps = state => ({
myVar: state.myVarFromReducer,
});
const mapDispatchToProps = dispatch => ({
expandFn: () => expand(dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(myComponent);
让我们忽略mapDispatchToProps
,它不会用于我们的关注
我邀请您查看并更好地理解redux和react之间的联系
注意:此代码示例经常出现在组件文件的末尾
我们这里有一个绑定connect(mapStateToProps,…)(myComponent)
,它与我的组件处于指定状态。
例如,指定的状态是您在src/store/Stage.js中定义的值
因此,在您的情况下,您必须将您的组件与存储连接起来,具体操作方法如上所述。
然后,您必须映射要在组件状态中包含的减速器状态的信息。
它将如下所示:
const mapStateToProps = state => ({
show: state.show,
});
基本上,这意味着“将组件状态的属性show
与减速器的属性show
绑定”
如果减速器的show
属性发生变化,将通知该部件,并更新其show
属性