我根据用户是教授,学生还是未登录来呈现不同的目标网页。目标网页非常相似;唯一的区别是显示的按钮。我知道我可以使用内联条件或简单的if-else语句来解决这个问题。但是,我想知道最佳实践在这种情况下实现条件呈现是什么。我知道更高阶的组件(HOC)可以提供帮助,但我不确定它们在这种特殊情况下是否过度。
要在同一页面上,以下是我目前使用if-else语句呈现的不同Landing组件。
Landing.js(未登记的用户):
import React from 'react';
import { withRouter } from 'react-router-dom';
import { compose } from 'recompose';
import { withEither } from '../../helpers/withEither';
import LandingStudent from './LandingStudent';
import LandingProfessor from './LandingProfessor';
import './Landing.css';
const Landing = ({ history }) => {
return(
<div className="header">
<div className="text-box">
<h1 className="header-primary">
<span className="header-primary-main">
QME
</span>
<span className="header-primary-sub">
the best way to ask questions
</span>
</h1>
</div>
</div>
);
};
export default Landing;
LandingProfessor.js
import React from 'react';
import { withRouter } from 'react-router-dom';
import RaisedButton from 'material-ui/RaisedButton';
import './Landing.css';
const LandingProfessor = ({ history }) => {
return(
<div className="header">
<div className="text-box">
<h1 className="header-primary">
<span className="header-primary-main">
QME
</span>
<span className="header-primary-sub">
the best way to ask questions
</span>
</h1>
<RaisedButton
className="btn-animated btn-landing"
label="Create Class"
onClick={() => history.push('/courses/new')}
/>
<RaisedButton
className="btn-animated btn-landing"
label="Dashboard"
onClick={() => history.push('/courses')}
/>
</div>
</div>
);
};
export default withRouter(LandingProfessor);
LandingStudent.js
import React from 'react';
import { withRouter } from 'react-router-dom';
import RaisedButton from 'material-ui/RaisedButton';
import './Landing.css';
const Landing = ({ history }) => {
return(
<div className="header">
<div className="text-box">
<h1 className="header-primary">
<span className="header-primary-main">
QME
</span>
<span className="header-primary-sub">
the best way to ask questions
</span>
</h1>
<RaisedButton
className="btn-animated btn"
label="Join Class"
onClick={() => history.push('/courses/join')}
/>
</div>
</div>
);
};
export default withRouter(Landing);
答案 0 :(得分:0)
A&#39;技巧&#39;可以在景观的根div上附加一个className,即&#39; student&#39; &#39;教授&#39;或者&#39;退出&#39;并使用css display:none来隐藏每个场景中不需要的项目
另一种方法是保留3个组件,但将所有渲染委托给一个普通的LandingRenderer&#39;可以接受布尔属性的组件,例如&#39; showJoinClassButton&#39; &#39; showCreateButtonButton&#39;等
然后你的3个组件呈现就像这样的内容
LandingProfessor: (props) => (
<LandingRenderer
showJoinClassButton={false}
showCreateClassButton={true}
...
{...props} />
)
答案 1 :(得分:0)
我会在这里选择合成而不是继承,这意味着创建许多可重用的组件,并使用那些可重用的组件构建顶级组件,而不是让您的顶级组件从一个公共组件类型继承。如果你采用后一种方法,你可能会得到一个我认为比现在更好的道具清单。
首先,您可以对标题进行组件化:
Header.js
export default function Header(props) {
return (
<h1 className="header-primary">
{props.children}
</h1>
);
}
Header.Main = function HeaderMain(props) {
return (
<span className="header-primary-main">
{props.children}
</span>
);
};
Header.Sub = function HeaderSub(props) {
return (
<span className="header-primary-sub">
{props.children}
</span>
);
};
并在Landing.js中使用它:
import Header from './Header.js';
const Landing = ({ history }) => {
return(
<div className="header">
<div className="text-box">
<Header>
<Header.Main>QME</Header.Main>
<Header.Sub>the best way to ask questions</Header.Sub>
</Header>
</div>
</div>
);
}
答案 2 :(得分:0)
在这种特殊情况下,我认为临时性的做法并不过分。 我认为只要可以使用hoc来提高可读性和可用性,就可以使用它。
使用recompose个临时文件夹(您应该安装重新组合:npm install recompose
)
export const renderByConditions = (...conditions) => compose(
...conditions.map(condition =>
branch(condition[0], (condition[1] && renderComponent(condition[1])) || renderNothing, condition[2] && renderComponent(condition[2]))
)
)
您应该传递带有签名的数组:
[{condition
,left
(如果条件为真),right
(其他)]
condition - (ownProps) => youCondition
left - Component | empty
right - Component | empty
当left为空时-如果条件为true,它将呈现null。
当right为空时-如果条件不为真,它将呈现我们包装的组件
然后您可以使用临时选项:
renderByConditions(
[props => props.landing, props => <Landing {...props}/>],
[props => props.proffesor, LandingProfessor],
[props => props.student, LandingStudent],
[Component => Component, DefaultComponent]
)
我建议您开始使用重组hoc,它们很棒!