sideBar:{
open:false,
type:'temporary'
}
去掉这段代码就不会死循环了,这是为什么
import {
SET_COLUMN,
SET_BODY_WIDTH,
TOGGLE_SIDEBAR,
SET_SIDEBAR,
SET_IS_MY_SITES
} from '../actions'
let layoutInfo={
column:11,
bodyWidth:0,
isMySites:false,
showSiteSidebar:false,
sideBar:{
open: true,
type:'persistent'//temporary
}
};
const layout = (state=layoutInfo,action)=>{
switch (action.type){
case SET_COLUMN:
console.log('SET_COLUMN');
return {
...state,
column:action.column
};
case SET_BODY_WIDTH:
console.log('SET_BODY_WIDTH');
return{
...state,
bodyWidth:action.width,
showSiteSidebar:action.width>1024&&state.isMySites,
sideBar:{
open:action.width>1024&&!state.isMySites,
type:action.width>1024?'persistent':'temporary'
}
};
case TOGGLE_SIDEBAR:
console.log('TOGGLE_SIDEBAR');
return{
...state,
column:state.sideBar.open?10:11,
sideBar:{
...state.sideBar,
open:!state.sideBar.open
}
};
case SET_SIDEBAR:
console.log('SET_SIDEBAR');
return{
...state,
sideBar:action.sideBar
};
case SET_IS_MY_SITES:
console.log('SET_IS_MY_SITES');
let isSite =state.bodyWidth>1024&&action.isMySites;
return isSite?{
...state,
showSiteSidebar:isSite,
isMySites:action.isMySites,
//start
sideBar:{
open:false,
type:'temporary'
}
//end:去掉这段代码就不会死循环了,这是为什么
}:{
...state,
showSiteSidebar:isSite,
isMySites:action.isMySites
};
default:
return state;
}
};
export default layout;
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import classNames from 'classnames';
import Topbar from '../components/layout/Topbar'
import Sidebar from '../components/layout/Sidebar'
import {Route,withRouter} from 'react-router-dom'
import {getUserInfo} from '../utils'
import VerifyEmailDlg from './Dialog/VerifyEmailDlg'
import SitesSidebar from '../components/layout/SitesSidebar'
import {connect} from 'react-redux';
import {setBodyWidth,setIsMySites,setSidebar} from '../actions'
const styles = theme => ({
root: {
width: '100%',
height: '100%',
zIndex: 1,
overflow: 'hidden',
},
appFrame: {
display: 'flex',
width: '100%',
height: '100%',
},
content: {
position: 'absolute',
top: '56px',
right: 0,
left: 0,
bottom: 0,
marginLeft:0,
flexGrow: 1,
boxSizing:'border-box',
backgroundColor: '#fff',
padding:0,
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
height: 'calc(100% - 56px)'
},
contentShift: {
marginLeft: '240px',
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
},
});
class Layout extends React.Component {
constructor(props){
super(props);
this.state = {
showVerifyEmailDig:false,
user:null
};
}
componentWillMount(){
//this.showVerifyEmailDialog();
window.addEventListener('resize', this.resizeListener);
this.resizeListener();
}
componentWillUnmount(){
window.removeEventListener('resize', this.resizeListener);
}
//监听路由变化
componentWillReceiveProps(nextProps){
if (nextProps.location.pathname.indexOf('mysites')!=-1){
console.log('is ')
this.props.dispatch(setIsMySites(true));
}else{
console.log('no is ')
this.props.dispatch(setIsMySites(false));
}
};
resizeListener=()=> {
let bodyWidth = document.body.offsetWidth;
this.props.dispatch(setBodyWidth(bodyWidth));
};
showVerifyEmailDialog=()=>{
let that = this;
getUserInfo(function(isLogin,user){
if (isLogin&&user.is_active==0){
that.setState({
showVerifyEmailDig:true,
user:user
})
}
});
};
render() {
const { classes,width,showSiteSidebar,sideBar} = this.props;
console.log(`showSiteSidebar=${showSiteSidebar},sideBar.open=${sideBar.open}`)
console.log('add')
console.log(sideBar)
return (
<div className={classes.root}>
<VerifyEmailDlg
onClose={()=>{
this.setState({
showVerifyEmailDig:false
})
}}
showVerifyEmailDig={this.state.showVerifyEmailDig}
user={this.state.user}/>
<div className={classes.appFrame}>
<Topbar showSearchBar={width>1024}
handleDrawerOpen={this.handleDrawerOpen}/>
<Sidebar {...this.props.sideBar}/>
{showSiteSidebar ? <SitesSidebar/>:null}
<main className={classNames(classes.content,((showSiteSidebar||sideBar.open)&&width>1024) && classes.contentShift)}>
{this.props.children}
</main>
</div>
</div>
);
}
}
const mapStateToProps = state => {
return {
column:state.layout.column,
width:state.layout.bodyWidth,
sideBar:state.layout.sideBar,
showSiteSidebar:state.layout.showSiteSidebar,
isMySites:state.layout.isMySites
}
};
export default connect(mapStateToProps)(withRouter(withStyles(styles)(Layout)));
Sidebar.js
import React from 'react'
import PropTypes from 'prop-types';
import Drawer from 'material-ui/Drawer';
import classNames from 'classnames';
import { withStyles } from 'material-ui/styles';
import List, { ListItem, ListItemIcon, ListItemText } from 'material-ui/List';
import Divider from 'material-ui/Divider';
import IconButton from 'material-ui/IconButton';
import ChevronLeftIcon from 'material-ui-icons/ChevronLeft';
import PermIdentity from 'material-ui-icons/PermIdentity'
import Home from 'material-ui-icons/Home'
import Pets from 'material-ui-icons/Pets'
import Explore from 'material-ui-icons/Explore'
import Feedback from 'material-ui-icons/Feedback'
import Settings from 'material-ui-icons/Settings'
import Help from 'material-ui-icons/Help'
import {Link} from 'react-router-dom'
import {connect} from 'react-redux';
const drawerWidth = 240;
const styles = theme => ({
sidebarButton:{
marginLeft: 8,
marginRight: 8,
},
drawerPaper: {
position: 'fixed',
bottom:'0',
height: '100%',
width: drawerWidth,
backgroundColor:theme.palette.background.default,
borderRight:'none !important'
},
drawerHeader: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: '0 8px',
height: 56
},
listItem:{
paddingTop:'8px',
paddingBottom:'8px'
},
listItemTextRoot:{
fontSize:'15px'
}
});
class Sidebar extends React.Component{
constructor(props){
super(props);
}
render(){
const { classes,sideBar } = this.props;
return(
<Drawer
open={sideBar.open}
type={sideBar.type}
classes={{
paper: classes.drawerPaper,
}}>
<div>
<div className={classes.drawerHeader}>
<IconButton>
<ChevronLeftIcon />
</IconButton>
</div>
<Divider />
<List>
<ListItem
component={Link}
to="/"
button
classes={{
root:classes.listItem
}}>
<ListItemIcon>
<Home className={classNames(classes.sidebarButton)} />
</ListItemIcon>
<ListItemText classes={{
text:classes.listItemTextRoot
}} primary="首页">
</ListItemText>
</ListItem>
<ListItem
component={Link}
to="/explore"
button
classes={{
root:classes.listItem}}
>
<ListItemIcon>
<Explore className={classNames(classes.sidebarButton)} />
</ListItemIcon>
<ListItemText classes={{
text:classes.listItemTextRoot
}}
primary="发现">
</ListItemText>
</ListItem>
<ListItem
component={Link}
to="/user"
button
classes={{
root:classes.listItem
}}>
<ListItemIcon>
<PermIdentity className={classNames(classes.sidebarButton)} />
</ListItemIcon>
<ListItemText classes={{
text:classes.listItemTextRoot
}}
primary="个人主页" />
</ListItem>
<ListItem
component={Link}
to="/mysites"
button
classes={{
root:classes.listItem
}}>
<ListItemIcon>
<Pets className={classNames(classes.sidebarButton)}/>
</ListItemIcon>
<ListItemText classes={{
text:classes.listItemTextRoot
}} primary="我的网址" />
</ListItem>
<Divider />
<ListItem
component={Link}
to="/"
button
classes={{
root:classes.listItem
}}>
<ListItemIcon>
<Settings className={classNames(classes.sidebarButton)}/>
</ListItemIcon>
<ListItemText classes={{
text:classes.listItemTextRoot
}} primary="设置" />
</ListItem>
<ListItem
component={Link}
to="/"
button
classes={{
root:classes.listItem
}}>
<ListItemIcon>
<Help className={classNames(classes.sidebarButton)}/>
</ListItemIcon>
<ListItemText classes={{
text:classes.listItemTextRoot
}} primary="帮助" />
</ListItem>
<ListItem
component={Link}
to="/"
button
classes={{
root:classes.listItem
}}>
<ListItemIcon>
<Feedback className={classNames(classes.sidebarButton)}/>
</ListItemIcon>
<ListItemText classes={{
text:classes.listItemTextRoot
}} primary="反馈" />
</ListItem>
</List>
</div>
</Drawer>
)
}
}
const mapStateToProps = state => {
return {
sideBar:state.layout.sideBar
}
};
export default connect(mapStateToProps)(withStyles(styles)(Sidebar));
Tobbar.js
import React from 'react'
import {withStyles} from 'material-ui/styles';
import AppBar from 'material-ui/AppBar';
import classNames from 'classnames';
import Toolbar from 'material-ui/Toolbar';
import IconButton from 'material-ui/IconButton';
import MenuIcon from 'material-ui-icons/Menu';
import Typography from 'material-ui/Typography';
import SearchIcon from 'material-ui-icons/Search'
import Avatar from 'material-ui/Avatar';
import Button from 'material-ui/Button';
import Notification from 'material-ui-icons/Notifications'
import Apps from 'material-ui-icons/Apps'
import SearchBar from 'material-ui-search-bar'
import {withRouter} from 'react-router-dom'
import {connect} from 'react-redux';
import {getLoginAction, logout,setColumn,toggleSideBar} from '../../actions'
class Topbar extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
}
}
componentWillMount() {
this.props.getLoginInfo();
}
login = () => {
this.props.history.push('/account/login')
};
quit = () => {
this.props.logout();
};
handleDrawerOpen=()=>{
this.props.setSideBar();
};
render() {
const {classes} = this.props;
return (
<AppBar className={classNames(classes.appBar)} classes={{
root: classes.appBarRoot
}}>
<Toolbar disableGutters classes={{
root: classes.toolbarRoot
}}>
<div className={classes.topBarLeft}>
<IconButton
color="contrast"
aria-label="open drawer"
onClick={this.handleDrawerOpen}
className={classNames(classes.menuButton)}
>
<MenuIcon />
</IconButton>
<img className={classes.logoImg} src={require('../../../images/awbeci-logo.png')} width={25}
height={25}/>
<Typography type="title" color="inherit" noWrap>
Awbeci
</Typography>
</div>
<div className={classes.flexCenter}>
{ this.props.showSearchBar &&
<SearchBar
hintText="搜索"
onChange={() => console.log('onChange')}
onRequestSearch={() => console.log('onRequestSearch')}
className={classes.searchBar}
/>
}
</div>
<div className={classes.topBarRight}>
{ !this.props.showSearchBar && <IconButton
color="contrast"
classes={{
root: classes.iconBtn
}}
aria-label="open drawer"
onClick={this.props.handleDrawerOpen}
>
<SearchIcon/>
</IconButton>}
{
this.props.isLogin ? (
<div>
<IconButton
color="contrast"
classes={{
root: classes.iconBtn
}}
aria-label="应用"
onClick={this.props.handleDrawerOpen}>
<Apps />
</IconButton>
<IconButton
color="contrast"
classes={{
root: classes.iconBtn
}}
aria-label="通知"
onClick={this.props.handleDrawerOpen}>
<Notification />
</IconButton>
<IconButton
color="contrast"
classes={{
root: classes.iconBtnAvatar
}}
aria-label="头像"
onClick={this.quit}>
<Avatar alt="Remy Sharp"
src={require('../../../images/zhangwei.png')}
className={classes.avatar}/>
</IconButton>
</div>)
:
(<Button color="contrast"
onClick={this.login}>登录</Button>)
}
</div>
</Toolbar>
</AppBar>
)
}
}
const mapStateToProps = state => {
return {
isLogin: state.user.isLogin,
sideBar:state.layout.sideBar
}
};
const mapDispatchToProps = (dispatch,ownProps) => {
return {
getLoginInfo: () => {
dispatch(getLoginAction())
},
logout: () => {
dispatch(logout())
},
setSideBar:()=>{
dispatch(toggleSideBar())
}
}
};
const styles = theme => ({
appBar: {
zIndex: '1499',
boxShadow: 'none !important'
},
appBarRoot: {},
toolbarRoot: {
[theme.breakpoints.up('sm')]: {
minHeight: '56px'
},
},
menuButton: {
marginLeft: 12,
marginRight: 12,
},
iconBtn: {
width: 32
},
iconBtnAvatar: {},
logoImg: {
marginRight: 8
},
avatar: {
width: 30,
height: 30
},
flex: {
flex: 1,
},
flexCenter: {
display: 'flex',
alignItems: 'center',
flex: 1
},
input: {
color: '#fff',
margin: theme.spacing.unit,
},
topBarLeft: {
width: 240,
display: 'flex',
position: 'relative',
alignItems: 'center'
},
searchBar: {
margin: '0 auto',
width: '500px !important',
maxWidth: 500
},
topBarRight: {
minWidth: 120,
width: 160,
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
boxSizing: 'border-box',
padding: '0 12px'
},
flexRight: {
display: 'flex',
alignItems: 'center'
}
});
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(Topbar)));
说明下原因:componentWillReceiveProps本就是当props发生改变时触发的事件,所以当在componentWillReceiveProps里面改变props值本身就有问题。心寒啊,这么久才找到问题的根本!!!
就可以了
参考:react-router-config