React Hooks:useCallback return 值未被汉堡包菜单 onClick 识别
React Hooks: useCallback return value not being recognized for hamburger menu onClick
我的应用程序中有一个组件可以处理两件事,
应用程序的布局(移动设备与桌面设备)以及其中的导航。这是一个 class 实现。
import React, { Component, createRef } from 'react';
import { Link, NavLink } from 'react-router-dom';
import Modal from '../components/Modal/MyModal.jsx';
import {
Container,
Menu,
Responsive,
Segment,
Visibility,
Sidebar,
Icon,
Button
} from 'semantic-ui-react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { modalStateOn, modalStateOff } from '../store/reducers/ui/index';
import { loadAvatar } from '../store/reducers/users/index';
const getWidth = () => {
const isSSR = typeof window === 'undefined';
return isSSR ? Responsive.onlyTablet.minWidth : window.innerWidth;
};
const logOutMenuItemHelper = (
isMobile,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
) => {
function mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
handleSidebarHide
) {
if (nav.name === 'Log in') {
console.log('mobile nav.name ', nav.name);
return (
<React.Fragment key={'modalForMobile'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message=" Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForMobile'}
name="Log out"
onClick={event => {
modalStateOn();
handleSidebarHide();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={() => {
handleSidebarHide();
}}
/>
);
}
}
function desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
) {
if (nav.name === 'Log in') {
return (
<React.Fragment key={'modalForDesktop'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message="Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForDesktop'}
name="Log out"
onClick={event => {
modalStateOn();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
return (
<Menu.Item exact key={nav.name} as={NavLink} to={nav.path} name={nav.name} />
);
}
}
if (isMobile && isLoggedIn) {
return mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
);
}
return desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
};
class DesktopContainer extends Component {
state = {};
hideFixedMenu = () => this.setState({ fixed: false });
showFixedMenu = () => this.setState({ fixed: true });
render() {
const { fixed } = this.state;
const {
history,
data,
children,
isLoggedIn,
modalActive,
modalStateOn,
modalStateOff
} = this.props;
// console.log("this.props desktop in LinkNAV ", this.props);
return (
<Responsive getWidth={getWidth} minWidth={Responsive.onlyTablet.minWidth}>
<Visibility
once={false}
onBottomPassed={this.showFixedMenu}
onBottomPassedReverse={this.hideFixedMenu}
>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '0' }}
vertical
>
<Menu
fixed={fixed ? 'top' : null}
inverted={!fixed}
pointing={!fixed}
secondary={!fixed}
size="large"
>
{/* {console.log("isLoggedIn in desktop homecomponent ", isLoggedIn)} */}
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
false,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
exact
key={nav.path}
as={NavLink}
to={nav.path}
name={nav.name}
/>
);
})}
</Menu>
</Segment>
</Visibility>
{children}
</Responsive>
);
}
}
class MobileContainer extends Component {
state = {};
handleSidebarHide = () => this.setState({ sidebarOpened: false });
handleToggle = () => this.setState({ sidebarOpened: true });
render() {
const {
children,
history,
data,
isLoggedIn,
modalActive,
modalStateOn,
modalStateOff
} = this.props;
const { sidebarOpened } = this.state;
return (
<Responsive
as={Sidebar.Pushable}
getWidth={getWidth}
maxWidth={Responsive.onlyMobile.maxWidth}
>
<Sidebar
as={Menu}
animation="push"
inverted
onHide={this.handleSidebarHide}
vertical
visible={sidebarOpened}
>
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
false,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
this.handleSidebarHide
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={this.handleSidebarHide}
/>
);
})}
</Sidebar>
<Sidebar.Pusher dimmed={sidebarOpened}>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '1em 0em' }}
vertical
>
<Container>
<Menu inverted pointing secondary size="large">
<Menu.Item onClick={this.handleToggle}>
<Icon name="sidebar" />
</Menu.Item>
<Menu.Item position="right">
<Button inverted>
{isLoggedIn ? (
<Link to="/">Log out</Link>
) : (
<Link to="/login">Log in</Link>
)}
</Button>
{!isLoggedIn ? (
<Button inverted style={{ marginLeft: '0.5em' }}>
<Link to="/register">
<span>Register!</span>
</Link>
</Button>
) : null}
</Menu.Item>
</Menu>
</Container>
</Segment>
{children}
</Sidebar.Pusher>
</Responsive>
);
}
}
const LinkNavWithLayout = ({
children,
history,
data,
userAvatar,
modalActive,
modalStateOn,
modalStateOff,
isLoggedIn
}) => (
<React.Fragment>
<DesktopContainer
history={history}
data={data}
userAvatar={userAvatar}
modalActive={modalActive}
modalStateOn={modalStateOn}
modalStateOff={modalStateOff}
isLoggedIn={isLoggedIn}
>
{children}
</DesktopContainer>
<MobileContainer
history={history}
data={data}
userAvatar={userAvatar}
modalActive={modalActive}
modalStateOn={modalStateOn}
modalStateOff={modalStateOff}
isLoggedIn={isLoggedIn}
>
{children}
</MobileContainer>
</React.Fragment>
);
function mapStateToProps(state) {
const { ui, users } = state;
const { isLoggedIn, userAvatar } = users;
const { modalActive } = ui;
return { isLoggedIn, userAvatar, modalActive };
}
const mapDispatchToProps = dispatch =>
bindActionCreators({ modalStateOn, modalStateOff, loadAvatar }, dispatch);
export default connect(
mapStateToProps,
mapDispatchToProps
)(LinkNavWithLayout);
此代码段包含使用 classes 编写的组件。这就是它的样子 like.
但是在将其切换为功能后,有两件事停止了工作:
移动侧抽屉无法打开和关闭。但是,如果使用硬编码值 true
,当您进入移动视图时,它确实会打开。
第二个是,当路由器更改 URL 时,相应的组件不会呈现。例如/profile
应该带一个到个人资料页面
为了解决汉堡包菜单问题,我尝试使用 useCallback
,我认为这是处理正确渲染的一些好策略。但无济于事。基本上是一个总是 return 正确值的函数。 Open menu === true
和 Closed menu === false
我什至设置了一个 useEffect
钩子来触发 isToggled
值的日志,只是为了确保事情是正确的。
var useToggle = initialState => {
const [isToggled, setIsToggled] = React.useState(initialState);
const toggle = useCallback(() => setIsToggled(state => !state), [setIsToggled]);
return [isToggled, toggle];
};
var [fixed, setFixed] = useState(null);
var [isToggled, toggle] = useToggle(false);
var [Content, setContent] = useState(null);
var [isMobile, setIsMobile] = useState(false);
var [isDesktop, setIsDesktop] = useState(false);
var handleSidebarHide = () => false;
var hideFixedMenu = () => setFixed(false);
var showFixedMenu = () => setFixed(true);
useEffect(() => {
console.log('isToggled', isToggled);
}, [isToggled]);
这是完整的组件:
import React, { useCallback, useState, useEffect, useContext } from 'react';
import { Link, NavLink } from 'react-router-dom';
import Modal from '../components/Modal/MyModal.jsx';
import {
Container,
Menu,
Responsive,
Segment,
Visibility,
Sidebar,
Icon,
Button
} from 'semantic-ui-react';
import { connect } from 'react-redux';
import { modalStateOn, modalStateOff } from '../store/reducers/ui/index';
import UserContext from '../components/UserContext/UserContext.jsx';
const getWidth = () => {
const isSSR = typeof window === 'undefined';
return isSSR ? Responsive.onlyTablet.minWidth : window.innerWidth;
};
function logOutMenuItemHelper(
isMobile,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
) {
function mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
handleSidebarHide
) {
if (nav.name === 'Log in') {
return (
<React.Fragment key={'modalForMobile'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message=" Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForMobile'}
name="Log out"
onClick={event => {
modalStateOn();
handleSidebarHide();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={() => {
handleSidebarHide();
}}
/>
);
}
}
function desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
) {
if (nav.name === 'Log in') {
return (
<React.Fragment key={'modalForDesktop'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message="Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForDesktop'}
name="Log out"
onClick={event => {
modalStateOn();
window.localStorage.clear();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
return (
<Menu.Item exact key={nav.name} as={NavLink} to={nav.path} name={nav.name} />
);
}
}
if (isMobile && isLoggedIn) {
return mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
handleSidebarHide
);
}
return desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
}
function LayoutContainer({
children,
history,
data,
isLoggedIn,
modalActive,
modalStateOn,
modalStateOff,
userData
}) {
var useToggle = initialState => {
const [isToggled, setIsToggled] = React.useState(initialState);
const toggle = useCallback(() => setIsToggled(state => !state), [setIsToggled]);
return [isToggled, toggle];
};
var [fixed, setFixed] = useState(null);
var [isToggled, toggle] = useToggle(false);
var [Content, setContent] = useState(null);
var [isMobile, setIsMobile] = useState(false);
var [isDesktop, setIsDesktop] = useState(false);
var handleSidebarHide = () => false;
// var handleToggle = () => setSideBarOpened(true);
var hideFixedMenu = () => setFixed(false);
var showFixedMenu = () => setFixed(true);
useEffect(() => {
console.log('isToggled', isToggled);
}, [isToggled]);
useEffect(() => {
console.log('window.innerWidth in first render', window.innerWidth);
if (window.innerWidth < 768) {
setIsMobile(true);
setIsDesktop(false);
} else {
setIsDesktop(true);
setIsMobile(false);
}
console.log('isMobile, isDesktop 175', isMobile, isDesktop);
}, []);
useEffect(() => {
window.addEventListener(
'resize',
function(e) {
if (e.target.innerWidth < 768) {
setIsMobile(isMobile => true);
setIsDesktop(isDesktop => false);
}
if (e.target.innerWidth > 767) {
setIsDesktop(isDesktop => true);
setIsMobile(isMobile => false);
}
},
false
);
console.log('Line 194', isMobile, isDesktop);
}, [isMobile, isDesktop]);
useEffect(() => {
if (window.innerWidth < 768) {
setContent(Content => (
<Responsive
as={Sidebar.Pushable}
getWidth={getWidth}
maxWidth={Responsive.onlyMobile.maxWidth}
>
<Sidebar
as={Menu}
animation="push"
inverted
onHide={handleSidebarHide}
vertical
visible={isToggled}
>
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
true,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={handleSidebarHide}
/>
);
})}
</Sidebar>
<Sidebar.Pusher dimmed={isToggled}>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '1em 0em' }}
vertical
>
<Container>
<Menu inverted pointing secondary size="large">
<Menu.Item onClick={() => toggle()}>
<Icon name="sidebar" />
</Menu.Item>
<Menu.Item position="right">
<Button inverted>
{isLoggedIn ? (
<Link to="#" onClick={modalStateOn}>
Log out
</Link>
) : (
<Link to="/login">Log in</Link>
)}
</Button>
{!isLoggedIn ? (
<Button inverted style={{ marginLeft: '0.5em' }}>
<Link to="/register">
<span>Register!</span>
</Link>
</Button>
) : null}
</Menu.Item>
</Menu>
</Container>
</Segment>
{React.cloneElement(children, { userData })}
</Sidebar.Pusher>
</Responsive>
));
} else {
setContent(Content => (
<Responsive getWidth={getWidth} minWidth={Responsive.onlyTablet.minWidth}>
<Visibility
once={false}
onBottomPassed={showFixedMenu}
onBottomPassedReverse={hideFixedMenu}
>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '0' }}
vertical
>
<Menu
fixed={fixed ? 'top' : null}
inverted={!fixed}
pointing={!fixed}
secondary={!fixed}
size="large"
>
{/* {console.log("isLoggedIn in desktop homecomponent ", isLoggedIn)} */}
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
false,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
exact
key={nav.path}
as={NavLink}
to={nav.path}
name={nav.name}
/>
);
})}
</Menu>
</Segment>
</Visibility>
{React.cloneElement(children, { userData })}
</Responsive>
));
}
}, [isMobile, isDesktop]);
return isMobile ? Content : Content;
}
const LinkNavWithLayout = ({
children,
history,
data,
modalActive,
modalStateOn,
modalStateOff,
isLoggedIn
}) => {
var userData = useContext(UserContext);
return (
<React.Fragment>
<LayoutContainer
history={history}
data={data}
modalActive={modalActive}
modalStateOn={modalStateOn}
modalStateOff={modalStateOff}
isLoggedIn={isLoggedIn}
userData={userData}
>
{children}
</LayoutContainer>
</React.Fragment>
);
};
function mapStateToProps(state) {
const { ui, users } = state;
const { isLoggedIn } = users;
const { modalActive } = ui;
return { isLoggedIn, modalActive };
}
const mapDispatchToProps = dispatch => ({
modalStateOn: () => dispatch(modalStateOn()),
modalStateOff: () => dispatch(modalStateOff())
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(LinkNavWithLayout);
提前致谢!
看来我忘记了这个布局的一个重要方面以及它向功能版本的转变!
除了处理由于浏览器宽度变化而导致的组件的不同布局外,我忘记在 useEffect
挂钩中添加其他重要的功能依赖项(汉堡侧面板、模态功能等) .).特别是 fixed, children, isToggled, modalActive
.
当我继续参考 class 版本以获取它所依赖的那些 prop/state
值时,功能组件自然在外观和感觉上比原始版本(class 版本)有所改进.
这是仅使用挂钩的新更新版本 \o/
import React, { useCallback, useState, useEffect, useContext } from 'react';
import { Link, NavLink } from 'react-router-dom';
import Modal from '../components/Modal/MyModal.jsx';
import {
Container,
Menu,
Responsive,
Segment,
Visibility,
Sidebar,
Icon,
Button
} from 'semantic-ui-react';
import { connect } from 'react-redux';
import { modalStateOn, modalStateOff } from '../store/reducers/ui/index';
import UserContext from '../components/UserContext/UserContext.jsx';
const getWidth = () => {
const isSSR = typeof window === 'undefined';
return isSSR ? Responsive.onlyTablet.minWidth : window.innerWidth;
};
function logOutMenuItemHelper(
isMobile,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
) {
function mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
handleSidebarHide
) {
if (nav.name === 'Log in') {
return (
<React.Fragment key={'modalForMobile'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message=" Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForMobile'}
name="Log out"
onClick={event => {
modalStateOn();
handleSidebarHide();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
console.log('nav.path ', nav.path);
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={handleSidebarHide}
/>
);
}
}
function desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
) {
if (nav.name === 'Log in') {
return (
<React.Fragment key={'modalForDesktop'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message="Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForDesktop'}
name="Log out"
onClick={event => {
modalStateOn();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
return (
<Menu.Item exact key={nav.name} as={NavLink} to={nav.path} name={nav.name} />
);
}
}
if (isMobile && isLoggedIn) {
return mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
handleSidebarHide
);
}
return desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
}
function LayoutContainer({
children,
history,
data,
isLoggedIn,
modalActive,
modalStateOn,
modalStateOff,
userData
}) {
var useToggle = initialState => {
const [isToggled, setIsToggled] = React.useState(initialState);
const toggle = useCallback(() => setIsToggled(state => !state), [setIsToggled]);
return [isToggled, toggle];
};
var [data, setData] = useState(data);
var [fixed, setFixed] = useState(null);
var [isToggled, toggle] = useToggle(false);
var [Content, setContent] = useState(null);
var [isMobile, setIsMobile] = useState(false);
var [isDesktop, setIsDesktop] = useState(false);
function handleSidebarHide() {
if (isToggled == true) return toggle();
}
// var handleToggle = () => setSideBarOpened(true);
var hideFixedMenu = () => setFixed(false);
var showFixedMenu = () => setFixed(true);
useEffect(() => {
console.log('isToggled ', isToggled);
}, [isToggled]);
useEffect(() => {
console.log('window.innerWidth in first render', window.innerWidth);
if (window.innerWidth < 768) {
setIsMobile(true);
setIsDesktop(false);
} else {
setIsDesktop(true);
setIsMobile(false);
}
console.log('isMobile, isDesktop 192', isMobile, isDesktop);
}, []);
useEffect(() => {
window.addEventListener(
'resize',
function(e) {
if (e.target.innerWidth < 768) {
setIsMobile(isMobile => true);
setIsDesktop(isDesktop => false);
}
if (e.target.innerWidth > 767) {
setIsDesktop(isDesktop => true);
setIsMobile(isMobile => false);
}
},
false
);
console.log('isMobile, isDesktop Line 194', isMobile, isDesktop);
}, [isMobile, isDesktop]);
useEffect(() => {
if (window.innerWidth < 768) {
setContent(Content => {
return (
<Responsive
as={Sidebar.Pushable}
getWidth={getWidth}
maxWidth={Responsive.onlyMobile.maxWidth}
>
<Sidebar
as={Menu}
animation="push"
inverted
onHide={() => handleSidebarHide()}
vertical
visible={isToggled}
>
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
true,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={handleSidebarHide}
/>
);
})}
</Sidebar>
<Sidebar.Pusher dimmed={isToggled}>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '1em 0em' }}
vertical
>
<Container>
<Menu inverted pointing secondary size="large">
<Menu.Item onClick={toggle}>
<Icon name="sidebar" />
</Menu.Item>
<Menu.Item position="right">
<Button inverted>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message="Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
{isLoggedIn ? (
<Link to="/" onClick={modalStateOn}>
Log out
</Link>
) : (
<Link to="/login">Log in</Link>
)}
</Button>
{!isLoggedIn ? (
<Button inverted style={{ marginLeft: '0.5em' }}>
<Link to="/register">
<span>Register!</span>
</Link>
</Button>
) : null}
</Menu.Item>
</Menu>
</Container>
</Segment>
{React.cloneElement(children, { userData })}
</Sidebar.Pusher>
</Responsive>
);
});
} else {
setContent(Content => (
<Responsive getWidth={getWidth} minWidth={Responsive.onlyTablet.minWidth}>
<Visibility
once={false}
onBottomPassed={showFixedMenu}
onBottomPassedReverse={hideFixedMenu}
>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '0' }}
vertical
>
<Menu
fixed={fixed ? 'top' : null}
inverted={!fixed}
pointing={!fixed}
secondary={!fixed}
size="large"
>
{/* {console.log("isLoggedIn in desktop homecomponent ", isLoggedIn)} */}
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
false,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
key={nav.path}
as={NavLink}
to={nav.path}
name={nav.name}
/>
);
})}
</Menu>
</Segment>
</Visibility>
{React.cloneElement(children, { userData })}
</Responsive>
));
}
}, [fixed, children, isMobile, isDesktop, isToggled, modalActive]);
return isMobile ? Content : Content;
}
const LinkNavWithLayout = ({
children,
history,
data,
modalActive,
modalStateOn,
modalStateOff,
isLoggedIn
}) => {
var userData = useContext(UserContext);
return (
<React.Fragment>
<LayoutContainer
history={history}
data={data}
modalActive={modalActive}
modalStateOn={modalStateOn}
modalStateOff={modalStateOff}
isLoggedIn={isLoggedIn}
userData={userData}
>
{children}
</LayoutContainer>
</React.Fragment>
);
};
function mapStateToProps(state) {
const { ui, users } = state;
const { isLoggedIn } = users;
const { modalActive } = ui;
return { isLoggedIn, modalActive };
}
const mapDispatchToProps = dispatch => ({
modalStateOn: () => dispatch(modalStateOn()),
modalStateOff: () => dispatch(modalStateOff())
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(LinkNavWithLayout);
我的应用程序中有一个组件可以处理两件事,
应用程序的布局(移动设备与桌面设备)以及其中的导航。这是一个 class 实现。
import React, { Component, createRef } from 'react';
import { Link, NavLink } from 'react-router-dom';
import Modal from '../components/Modal/MyModal.jsx';
import {
Container,
Menu,
Responsive,
Segment,
Visibility,
Sidebar,
Icon,
Button
} from 'semantic-ui-react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { modalStateOn, modalStateOff } from '../store/reducers/ui/index';
import { loadAvatar } from '../store/reducers/users/index';
const getWidth = () => {
const isSSR = typeof window === 'undefined';
return isSSR ? Responsive.onlyTablet.minWidth : window.innerWidth;
};
const logOutMenuItemHelper = (
isMobile,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
) => {
function mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
handleSidebarHide
) {
if (nav.name === 'Log in') {
console.log('mobile nav.name ', nav.name);
return (
<React.Fragment key={'modalForMobile'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message=" Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForMobile'}
name="Log out"
onClick={event => {
modalStateOn();
handleSidebarHide();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={() => {
handleSidebarHide();
}}
/>
);
}
}
function desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
) {
if (nav.name === 'Log in') {
return (
<React.Fragment key={'modalForDesktop'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message="Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForDesktop'}
name="Log out"
onClick={event => {
modalStateOn();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
return (
<Menu.Item exact key={nav.name} as={NavLink} to={nav.path} name={nav.name} />
);
}
}
if (isMobile && isLoggedIn) {
return mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
);
}
return desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
};
class DesktopContainer extends Component {
state = {};
hideFixedMenu = () => this.setState({ fixed: false });
showFixedMenu = () => this.setState({ fixed: true });
render() {
const { fixed } = this.state;
const {
history,
data,
children,
isLoggedIn,
modalActive,
modalStateOn,
modalStateOff
} = this.props;
// console.log("this.props desktop in LinkNAV ", this.props);
return (
<Responsive getWidth={getWidth} minWidth={Responsive.onlyTablet.minWidth}>
<Visibility
once={false}
onBottomPassed={this.showFixedMenu}
onBottomPassedReverse={this.hideFixedMenu}
>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '0' }}
vertical
>
<Menu
fixed={fixed ? 'top' : null}
inverted={!fixed}
pointing={!fixed}
secondary={!fixed}
size="large"
>
{/* {console.log("isLoggedIn in desktop homecomponent ", isLoggedIn)} */}
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
false,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
exact
key={nav.path}
as={NavLink}
to={nav.path}
name={nav.name}
/>
);
})}
</Menu>
</Segment>
</Visibility>
{children}
</Responsive>
);
}
}
class MobileContainer extends Component {
state = {};
handleSidebarHide = () => this.setState({ sidebarOpened: false });
handleToggle = () => this.setState({ sidebarOpened: true });
render() {
const {
children,
history,
data,
isLoggedIn,
modalActive,
modalStateOn,
modalStateOff
} = this.props;
const { sidebarOpened } = this.state;
return (
<Responsive
as={Sidebar.Pushable}
getWidth={getWidth}
maxWidth={Responsive.onlyMobile.maxWidth}
>
<Sidebar
as={Menu}
animation="push"
inverted
onHide={this.handleSidebarHide}
vertical
visible={sidebarOpened}
>
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
false,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
this.handleSidebarHide
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={this.handleSidebarHide}
/>
);
})}
</Sidebar>
<Sidebar.Pusher dimmed={sidebarOpened}>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '1em 0em' }}
vertical
>
<Container>
<Menu inverted pointing secondary size="large">
<Menu.Item onClick={this.handleToggle}>
<Icon name="sidebar" />
</Menu.Item>
<Menu.Item position="right">
<Button inverted>
{isLoggedIn ? (
<Link to="/">Log out</Link>
) : (
<Link to="/login">Log in</Link>
)}
</Button>
{!isLoggedIn ? (
<Button inverted style={{ marginLeft: '0.5em' }}>
<Link to="/register">
<span>Register!</span>
</Link>
</Button>
) : null}
</Menu.Item>
</Menu>
</Container>
</Segment>
{children}
</Sidebar.Pusher>
</Responsive>
);
}
}
const LinkNavWithLayout = ({
children,
history,
data,
userAvatar,
modalActive,
modalStateOn,
modalStateOff,
isLoggedIn
}) => (
<React.Fragment>
<DesktopContainer
history={history}
data={data}
userAvatar={userAvatar}
modalActive={modalActive}
modalStateOn={modalStateOn}
modalStateOff={modalStateOff}
isLoggedIn={isLoggedIn}
>
{children}
</DesktopContainer>
<MobileContainer
history={history}
data={data}
userAvatar={userAvatar}
modalActive={modalActive}
modalStateOn={modalStateOn}
modalStateOff={modalStateOff}
isLoggedIn={isLoggedIn}
>
{children}
</MobileContainer>
</React.Fragment>
);
function mapStateToProps(state) {
const { ui, users } = state;
const { isLoggedIn, userAvatar } = users;
const { modalActive } = ui;
return { isLoggedIn, userAvatar, modalActive };
}
const mapDispatchToProps = dispatch =>
bindActionCreators({ modalStateOn, modalStateOff, loadAvatar }, dispatch);
export default connect(
mapStateToProps,
mapDispatchToProps
)(LinkNavWithLayout);
此代码段包含使用 classes 编写的组件。这就是它的样子 like.
但是在将其切换为功能后,有两件事停止了工作:
移动侧抽屉无法打开和关闭。但是,如果使用硬编码值 true
,当您进入移动视图时,它确实会打开。
第二个是,当路由器更改 URL 时,相应的组件不会呈现。例如/profile
应该带一个到个人资料页面
为了解决汉堡包菜单问题,我尝试使用 useCallback
,我认为这是处理正确渲染的一些好策略。但无济于事。基本上是一个总是 return 正确值的函数。 Open menu === true
和 Closed menu === false
我什至设置了一个 useEffect
钩子来触发 isToggled
值的日志,只是为了确保事情是正确的。
var useToggle = initialState => {
const [isToggled, setIsToggled] = React.useState(initialState);
const toggle = useCallback(() => setIsToggled(state => !state), [setIsToggled]);
return [isToggled, toggle];
};
var [fixed, setFixed] = useState(null);
var [isToggled, toggle] = useToggle(false);
var [Content, setContent] = useState(null);
var [isMobile, setIsMobile] = useState(false);
var [isDesktop, setIsDesktop] = useState(false);
var handleSidebarHide = () => false;
var hideFixedMenu = () => setFixed(false);
var showFixedMenu = () => setFixed(true);
useEffect(() => {
console.log('isToggled', isToggled);
}, [isToggled]);
这是完整的组件:
import React, { useCallback, useState, useEffect, useContext } from 'react';
import { Link, NavLink } from 'react-router-dom';
import Modal from '../components/Modal/MyModal.jsx';
import {
Container,
Menu,
Responsive,
Segment,
Visibility,
Sidebar,
Icon,
Button
} from 'semantic-ui-react';
import { connect } from 'react-redux';
import { modalStateOn, modalStateOff } from '../store/reducers/ui/index';
import UserContext from '../components/UserContext/UserContext.jsx';
const getWidth = () => {
const isSSR = typeof window === 'undefined';
return isSSR ? Responsive.onlyTablet.minWidth : window.innerWidth;
};
function logOutMenuItemHelper(
isMobile,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
) {
function mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
handleSidebarHide
) {
if (nav.name === 'Log in') {
return (
<React.Fragment key={'modalForMobile'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message=" Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForMobile'}
name="Log out"
onClick={event => {
modalStateOn();
handleSidebarHide();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={() => {
handleSidebarHide();
}}
/>
);
}
}
function desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
) {
if (nav.name === 'Log in') {
return (
<React.Fragment key={'modalForDesktop'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message="Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForDesktop'}
name="Log out"
onClick={event => {
modalStateOn();
window.localStorage.clear();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
return (
<Menu.Item exact key={nav.name} as={NavLink} to={nav.path} name={nav.name} />
);
}
}
if (isMobile && isLoggedIn) {
return mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
handleSidebarHide
);
}
return desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
}
function LayoutContainer({
children,
history,
data,
isLoggedIn,
modalActive,
modalStateOn,
modalStateOff,
userData
}) {
var useToggle = initialState => {
const [isToggled, setIsToggled] = React.useState(initialState);
const toggle = useCallback(() => setIsToggled(state => !state), [setIsToggled]);
return [isToggled, toggle];
};
var [fixed, setFixed] = useState(null);
var [isToggled, toggle] = useToggle(false);
var [Content, setContent] = useState(null);
var [isMobile, setIsMobile] = useState(false);
var [isDesktop, setIsDesktop] = useState(false);
var handleSidebarHide = () => false;
// var handleToggle = () => setSideBarOpened(true);
var hideFixedMenu = () => setFixed(false);
var showFixedMenu = () => setFixed(true);
useEffect(() => {
console.log('isToggled', isToggled);
}, [isToggled]);
useEffect(() => {
console.log('window.innerWidth in first render', window.innerWidth);
if (window.innerWidth < 768) {
setIsMobile(true);
setIsDesktop(false);
} else {
setIsDesktop(true);
setIsMobile(false);
}
console.log('isMobile, isDesktop 175', isMobile, isDesktop);
}, []);
useEffect(() => {
window.addEventListener(
'resize',
function(e) {
if (e.target.innerWidth < 768) {
setIsMobile(isMobile => true);
setIsDesktop(isDesktop => false);
}
if (e.target.innerWidth > 767) {
setIsDesktop(isDesktop => true);
setIsMobile(isMobile => false);
}
},
false
);
console.log('Line 194', isMobile, isDesktop);
}, [isMobile, isDesktop]);
useEffect(() => {
if (window.innerWidth < 768) {
setContent(Content => (
<Responsive
as={Sidebar.Pushable}
getWidth={getWidth}
maxWidth={Responsive.onlyMobile.maxWidth}
>
<Sidebar
as={Menu}
animation="push"
inverted
onHide={handleSidebarHide}
vertical
visible={isToggled}
>
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
true,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={handleSidebarHide}
/>
);
})}
</Sidebar>
<Sidebar.Pusher dimmed={isToggled}>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '1em 0em' }}
vertical
>
<Container>
<Menu inverted pointing secondary size="large">
<Menu.Item onClick={() => toggle()}>
<Icon name="sidebar" />
</Menu.Item>
<Menu.Item position="right">
<Button inverted>
{isLoggedIn ? (
<Link to="#" onClick={modalStateOn}>
Log out
</Link>
) : (
<Link to="/login">Log in</Link>
)}
</Button>
{!isLoggedIn ? (
<Button inverted style={{ marginLeft: '0.5em' }}>
<Link to="/register">
<span>Register!</span>
</Link>
</Button>
) : null}
</Menu.Item>
</Menu>
</Container>
</Segment>
{React.cloneElement(children, { userData })}
</Sidebar.Pusher>
</Responsive>
));
} else {
setContent(Content => (
<Responsive getWidth={getWidth} minWidth={Responsive.onlyTablet.minWidth}>
<Visibility
once={false}
onBottomPassed={showFixedMenu}
onBottomPassedReverse={hideFixedMenu}
>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '0' }}
vertical
>
<Menu
fixed={fixed ? 'top' : null}
inverted={!fixed}
pointing={!fixed}
secondary={!fixed}
size="large"
>
{/* {console.log("isLoggedIn in desktop homecomponent ", isLoggedIn)} */}
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
false,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
exact
key={nav.path}
as={NavLink}
to={nav.path}
name={nav.name}
/>
);
})}
</Menu>
</Segment>
</Visibility>
{React.cloneElement(children, { userData })}
</Responsive>
));
}
}, [isMobile, isDesktop]);
return isMobile ? Content : Content;
}
const LinkNavWithLayout = ({
children,
history,
data,
modalActive,
modalStateOn,
modalStateOff,
isLoggedIn
}) => {
var userData = useContext(UserContext);
return (
<React.Fragment>
<LayoutContainer
history={history}
data={data}
modalActive={modalActive}
modalStateOn={modalStateOn}
modalStateOff={modalStateOff}
isLoggedIn={isLoggedIn}
userData={userData}
>
{children}
</LayoutContainer>
</React.Fragment>
);
};
function mapStateToProps(state) {
const { ui, users } = state;
const { isLoggedIn } = users;
const { modalActive } = ui;
return { isLoggedIn, modalActive };
}
const mapDispatchToProps = dispatch => ({
modalStateOn: () => dispatch(modalStateOn()),
modalStateOff: () => dispatch(modalStateOff())
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(LinkNavWithLayout);
提前致谢!
看来我忘记了这个布局的一个重要方面以及它向功能版本的转变!
除了处理由于浏览器宽度变化而导致的组件的不同布局外,我忘记在 useEffect
挂钩中添加其他重要的功能依赖项(汉堡侧面板、模态功能等) .).特别是 fixed, children, isToggled, modalActive
.
当我继续参考 class 版本以获取它所依赖的那些 prop/state
值时,功能组件自然在外观和感觉上比原始版本(class 版本)有所改进.
这是仅使用挂钩的新更新版本 \o/
import React, { useCallback, useState, useEffect, useContext } from 'react';
import { Link, NavLink } from 'react-router-dom';
import Modal from '../components/Modal/MyModal.jsx';
import {
Container,
Menu,
Responsive,
Segment,
Visibility,
Sidebar,
Icon,
Button
} from 'semantic-ui-react';
import { connect } from 'react-redux';
import { modalStateOn, modalStateOff } from '../store/reducers/ui/index';
import UserContext from '../components/UserContext/UserContext.jsx';
const getWidth = () => {
const isSSR = typeof window === 'undefined';
return isSSR ? Responsive.onlyTablet.minWidth : window.innerWidth;
};
function logOutMenuItemHelper(
isMobile,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
) {
function mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
handleSidebarHide
) {
if (nav.name === 'Log in') {
return (
<React.Fragment key={'modalForMobile'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message=" Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForMobile'}
name="Log out"
onClick={event => {
modalStateOn();
handleSidebarHide();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
console.log('nav.path ', nav.path);
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={handleSidebarHide}
/>
);
}
}
function desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
) {
if (nav.name === 'Log in') {
return (
<React.Fragment key={'modalForDesktop'}>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message="Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
<Menu.Item
key={'modalForDesktop'}
name="Log out"
onClick={event => {
modalStateOn();
}}
>
Log Out
</Menu.Item>
</React.Fragment>
);
} else {
return (
<Menu.Item exact key={nav.name} as={NavLink} to={nav.path} name={nav.name} />
);
}
}
if (isMobile && isLoggedIn) {
return mobilelogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
handleSidebarHide
);
}
return desktoplogOutMenuItemHelper(
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
}
function LayoutContainer({
children,
history,
data,
isLoggedIn,
modalActive,
modalStateOn,
modalStateOff,
userData
}) {
var useToggle = initialState => {
const [isToggled, setIsToggled] = React.useState(initialState);
const toggle = useCallback(() => setIsToggled(state => !state), [setIsToggled]);
return [isToggled, toggle];
};
var [data, setData] = useState(data);
var [fixed, setFixed] = useState(null);
var [isToggled, toggle] = useToggle(false);
var [Content, setContent] = useState(null);
var [isMobile, setIsMobile] = useState(false);
var [isDesktop, setIsDesktop] = useState(false);
function handleSidebarHide() {
if (isToggled == true) return toggle();
}
// var handleToggle = () => setSideBarOpened(true);
var hideFixedMenu = () => setFixed(false);
var showFixedMenu = () => setFixed(true);
useEffect(() => {
console.log('isToggled ', isToggled);
}, [isToggled]);
useEffect(() => {
console.log('window.innerWidth in first render', window.innerWidth);
if (window.innerWidth < 768) {
setIsMobile(true);
setIsDesktop(false);
} else {
setIsDesktop(true);
setIsMobile(false);
}
console.log('isMobile, isDesktop 192', isMobile, isDesktop);
}, []);
useEffect(() => {
window.addEventListener(
'resize',
function(e) {
if (e.target.innerWidth < 768) {
setIsMobile(isMobile => true);
setIsDesktop(isDesktop => false);
}
if (e.target.innerWidth > 767) {
setIsDesktop(isDesktop => true);
setIsMobile(isMobile => false);
}
},
false
);
console.log('isMobile, isDesktop Line 194', isMobile, isDesktop);
}, [isMobile, isDesktop]);
useEffect(() => {
if (window.innerWidth < 768) {
setContent(Content => {
return (
<Responsive
as={Sidebar.Pushable}
getWidth={getWidth}
maxWidth={Responsive.onlyMobile.maxWidth}
>
<Sidebar
as={Menu}
animation="push"
inverted
onHide={() => handleSidebarHide()}
vertical
visible={isToggled}
>
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
true,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff,
handleSidebarHide
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
exact
key={nav.name}
as={NavLink}
to={nav.path}
name={nav.name}
onClick={handleSidebarHide}
/>
);
})}
</Sidebar>
<Sidebar.Pusher dimmed={isToggled}>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '1em 0em' }}
vertical
>
<Container>
<Menu inverted pointing secondary size="large">
<Menu.Item onClick={toggle}>
<Icon name="sidebar" />
</Menu.Item>
<Menu.Item position="right">
<Button inverted>
{modalActive && (
<Modal
isAlertModal={false}
history={history}
affirmativeUsed="Yes"
message="Are you sure you want to log out of your account?"
modalActive={modalActive}
/>
)}
{isLoggedIn ? (
<Link to="/" onClick={modalStateOn}>
Log out
</Link>
) : (
<Link to="/login">Log in</Link>
)}
</Button>
{!isLoggedIn ? (
<Button inverted style={{ marginLeft: '0.5em' }}>
<Link to="/register">
<span>Register!</span>
</Link>
</Button>
) : null}
</Menu.Item>
</Menu>
</Container>
</Segment>
{React.cloneElement(children, { userData })}
</Sidebar.Pusher>
</Responsive>
);
});
} else {
setContent(Content => (
<Responsive getWidth={getWidth} minWidth={Responsive.onlyTablet.minWidth}>
<Visibility
once={false}
onBottomPassed={showFixedMenu}
onBottomPassedReverse={hideFixedMenu}
>
<Segment
inverted
textAlign="center"
style={{ minHeight: 'auto', padding: '0' }}
vertical
>
<Menu
fixed={fixed ? 'top' : null}
inverted={!fixed}
pointing={!fixed}
secondary={!fixed}
size="large"
>
{/* {console.log("isLoggedIn in desktop homecomponent ", isLoggedIn)} */}
{isLoggedIn
? data
.filter(function(nav) {
return nav.name !== 'Register';
})
.map(nav => {
return logOutMenuItemHelper(
false,
isLoggedIn,
history,
modalActive,
nav,
NavLink,
modalStateOn,
modalStateOff
);
})
: data
.filter(function(nav) {
return nav.name != 'Profile' && nav.name != 'Dashboard';
})
.map(nav => {
return (
<Menu.Item
key={nav.path}
as={NavLink}
to={nav.path}
name={nav.name}
/>
);
})}
</Menu>
</Segment>
</Visibility>
{React.cloneElement(children, { userData })}
</Responsive>
));
}
}, [fixed, children, isMobile, isDesktop, isToggled, modalActive]);
return isMobile ? Content : Content;
}
const LinkNavWithLayout = ({
children,
history,
data,
modalActive,
modalStateOn,
modalStateOff,
isLoggedIn
}) => {
var userData = useContext(UserContext);
return (
<React.Fragment>
<LayoutContainer
history={history}
data={data}
modalActive={modalActive}
modalStateOn={modalStateOn}
modalStateOff={modalStateOff}
isLoggedIn={isLoggedIn}
userData={userData}
>
{children}
</LayoutContainer>
</React.Fragment>
);
};
function mapStateToProps(state) {
const { ui, users } = state;
const { isLoggedIn } = users;
const { modalActive } = ui;
return { isLoggedIn, modalActive };
}
const mapDispatchToProps = dispatch => ({
modalStateOn: () => dispatch(modalStateOn()),
modalStateOff: () => dispatch(modalStateOff())
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(LinkNavWithLayout);