调用这个反应 HOC 感觉我可以用另一种方式抽象它请建议
Calling this react HOC feels like i could abstract this in another way please advice
我是初学者,需要建议。我学习了 Reactjs 并创建了这个 HOC,这样我就可以在 Router V6 中导航。我担心的是,从我的桌面 Navbar
和移动侧菜单我有指向相同 Dashboard
.
的链接
所以我创建了一个 HOC,因为它在两个位置都是相同的代码 运行,并且 HOC 现在有这个代码。
这是 HOC:
import React from 'react';
import AuthUserContext from './context';
import * as ROLES from '../constants/roles';
const WithDashboardNavigate = Component => {
class WithDashboardBase extends React.Component {
constructor() {
super();
this.onDashboard = this.onDashboard.bind(this);
}
onDashboard = navigate => {
const { authUser } = this.props;
if (authUser) {
if (authUser.roles.includes(ROLES.ANON)) {
navigate('/app/login');
} else if (authUser.roles.includes(ROLES.USER) || authUser.roles.includes(ROLES.ADMIN)) {
const view = localStorage.getItem('currentDashBoardView');
// Here if user has used nav menu earlier then that last view is loaded
if (view) navigate(view);
// or default to dash
else navigate('/app/dashboard');
}
}
};
render() {
return <Component dashboardNavigater={this.onDashboard} {...this.props} />;
}
}
const WithDashboard = () => (
<AuthUserContext.Consumer>
{authUser => (
<div>
<WithDashboardBase authUser={authUser} />
</div>
)}
</AuthUserContext.Consumer>
);
return WithDashboard;
};
export default WithDashboardNavigate;
我从 Navbar
中这样使用它:
function SignedInButton(props) {
const navigate = useNavigate();
function openDashboard() {
props.dashboardNavigater(navigate);
}
return (
<div>
<Button className="button is-large" onClick={openDashboard}>
<span className="icon is-medium">
<i className="fas fa-user" />
</span>
</Button>
</div>
);
}
export default WithDashboardNavigate(SignedInButton);
我从 SideMenu
中这样使用它:
/* eslint-disable jsx-a11y/anchor-is-valid */
import React from 'react';
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import WithDashboardNavigate from '../../session/WithDashboardNavigate';
function SideMenu(props) {
const { close, dashboardNavigater } = props;
const navigate = useNavigate();
const onProfilePageClick = () => {
if (close) close();
dashboardNavigater(navigate);
};
return (
<div>
<MenuLinksSpace />
<MenuLinks>
<li>
<a onClick={onProfilePageClick} role="presentation">
<span className="icon is-medium">
<i className="fas fa-user" />
</span>{' '}
Dashboard
</a>
</li>
</MenuLinks>
</div>
);
}
我的问题是我做得太过分了吗?我的意思是有没有更简单的方法来更好地符合 React 最佳实践?
这完全取决于需求和您的设计方式。我的观点是,如果您使用功能组件,则不需要与 class 组件和 bind(this).
混合使用
注意: 如果任何组件传递未传递给 WithDashboardBase 的道具,则您不会通过 WithDashboard 函数传递道具。
import React from 'react';
import AuthUserContext from './context';
import * as ROLES from '../constants/roles';
const WithDashboardNavigate = Component => {
const WithDashboardBase = (props) => {
const onDashboard = navigate => {
const { authUser } = props;
if (authUser) {
if (authUser.roles.includes(ROLES.ANON)) {
navigate('/app/login');
} else if (authUser.roles.includes(ROLES.USER) || authUser.roles.includes(ROLES.ADMIN)) {
const view = localStorage.getItem('currentDashBoardView');
// Here if user has used nav menu earlier then that last view is loaded
if (view) navigate(view);
// or default to dash
else navigate('/app/dashboard');
}
}
};
return <Component dashboardNavigater={onDashboard} {...props} />;
}
const WithDashboard = (props) => ( // Pass props from here as well
<AuthUserContext.Consumer>
{authUser => (
<div>
<WithDashboardBase authUser={authUser} {...props} />
</div>
)}
</AuthUserContext.Consumer>
);
return WithDashboard;
};
export default WithDashboardNavigate;
我已经为上下文API创建了连接 HOC(与 redux 相同)。检查这个它会帮助你理解从 parent 到 child 的道具传递。
https://stackblitz.com/edit/reactjs-usecontext-usereducer-state-management?file=src%2FStore.js
我是初学者,需要建议。我学习了 Reactjs 并创建了这个 HOC,这样我就可以在 Router V6 中导航。我担心的是,从我的桌面 Navbar
和移动侧菜单我有指向相同 Dashboard
.
所以我创建了一个 HOC,因为它在两个位置都是相同的代码 运行,并且 HOC 现在有这个代码。
这是 HOC:
import React from 'react';
import AuthUserContext from './context';
import * as ROLES from '../constants/roles';
const WithDashboardNavigate = Component => {
class WithDashboardBase extends React.Component {
constructor() {
super();
this.onDashboard = this.onDashboard.bind(this);
}
onDashboard = navigate => {
const { authUser } = this.props;
if (authUser) {
if (authUser.roles.includes(ROLES.ANON)) {
navigate('/app/login');
} else if (authUser.roles.includes(ROLES.USER) || authUser.roles.includes(ROLES.ADMIN)) {
const view = localStorage.getItem('currentDashBoardView');
// Here if user has used nav menu earlier then that last view is loaded
if (view) navigate(view);
// or default to dash
else navigate('/app/dashboard');
}
}
};
render() {
return <Component dashboardNavigater={this.onDashboard} {...this.props} />;
}
}
const WithDashboard = () => (
<AuthUserContext.Consumer>
{authUser => (
<div>
<WithDashboardBase authUser={authUser} />
</div>
)}
</AuthUserContext.Consumer>
);
return WithDashboard;
};
export default WithDashboardNavigate;
我从 Navbar
中这样使用它:
function SignedInButton(props) {
const navigate = useNavigate();
function openDashboard() {
props.dashboardNavigater(navigate);
}
return (
<div>
<Button className="button is-large" onClick={openDashboard}>
<span className="icon is-medium">
<i className="fas fa-user" />
</span>
</Button>
</div>
);
}
export default WithDashboardNavigate(SignedInButton);
我从 SideMenu
中这样使用它:
/* eslint-disable jsx-a11y/anchor-is-valid */
import React from 'react';
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import WithDashboardNavigate from '../../session/WithDashboardNavigate';
function SideMenu(props) {
const { close, dashboardNavigater } = props;
const navigate = useNavigate();
const onProfilePageClick = () => {
if (close) close();
dashboardNavigater(navigate);
};
return (
<div>
<MenuLinksSpace />
<MenuLinks>
<li>
<a onClick={onProfilePageClick} role="presentation">
<span className="icon is-medium">
<i className="fas fa-user" />
</span>{' '}
Dashboard
</a>
</li>
</MenuLinks>
</div>
);
}
我的问题是我做得太过分了吗?我的意思是有没有更简单的方法来更好地符合 React 最佳实践?
这完全取决于需求和您的设计方式。我的观点是,如果您使用功能组件,则不需要与 class 组件和 bind(this).
混合使用注意: 如果任何组件传递未传递给 WithDashboardBase 的道具,则您不会通过 WithDashboard 函数传递道具。
import React from 'react';
import AuthUserContext from './context';
import * as ROLES from '../constants/roles';
const WithDashboardNavigate = Component => {
const WithDashboardBase = (props) => {
const onDashboard = navigate => {
const { authUser } = props;
if (authUser) {
if (authUser.roles.includes(ROLES.ANON)) {
navigate('/app/login');
} else if (authUser.roles.includes(ROLES.USER) || authUser.roles.includes(ROLES.ADMIN)) {
const view = localStorage.getItem('currentDashBoardView');
// Here if user has used nav menu earlier then that last view is loaded
if (view) navigate(view);
// or default to dash
else navigate('/app/dashboard');
}
}
};
return <Component dashboardNavigater={onDashboard} {...props} />;
}
const WithDashboard = (props) => ( // Pass props from here as well
<AuthUserContext.Consumer>
{authUser => (
<div>
<WithDashboardBase authUser={authUser} {...props} />
</div>
)}
</AuthUserContext.Consumer>
);
return WithDashboard;
};
export default WithDashboardNavigate;
我已经为上下文API创建了连接 HOC(与 redux 相同)。检查这个它会帮助你理解从 parent 到 child 的道具传递。
https://stackblitz.com/edit/reactjs-usecontext-usereducer-state-management?file=src%2FStore.js