在使用 react框架 的时候中往往会遇到需要 条件渲染 的情形,这时候,许多人会设想采用if语句来实现,比如下面,当满足条件condition时,conditonRender渲染组件ComponentA,当不满足 条件时,渲染ComponentB
const conditionRender = () =>{
if(condition){
return <ComponentA />
}
else{
return <ComponentB />
}
}
其实,结合三木运算符以及JSX的语法糖,它在形式和逻辑上可以变得更紧凑一些,比如:
const conditionRender = () =>{
return {condition?<componentA />:<componentB />}
}
同样的一些情况,我们也可以尝试用&&运算符实现条件渲染,比如在满足条件condition时,conditonRender渲染组件Component
const conditionRender = () =>{
if(condition){
return <Component />
}
}
改成如下,因为&&运算符的特性,当condition为true时需要检查&&后面那个表达式boolean值(true or false),那么Component就被渲染出来,而当conditon为false时,不在检查&&运算符后面表达式的boolean值,那么Component就被隐藏了
const conditionRender = () =>{
return {condition&&<Component />}
}
总结:其实两者效果一样,但在大量而复杂的代码块里,&&运算符和三木运算符的合理使用显然会大大增强代码的可读性
在之前使用 AngularJS 开发项目半年左右时间的时候,整理过一篇 《AngularJS 常用模块书写建议》 ,那时候团队没有太注重规范,这篇类似规范的东西使得我后来参与的项目代码质量高了不少,也帮助了我们团队其他的同学。现在在一个比较正规的团队里,平时的前端开发以 React 为主,书写规范早已通过 lint 工具 加在 pre-commit hook
里强制解决。然而还是觉得有必要写一篇书写建议,这样或许能加深理解,而不是单单地改掉 lint
后的 error
或 warning
。
本文将以从上到下,从外到内的方式介绍如何规范地写一个 React 组件。
如果组件有内部状态、方法或者 refs
,使用 Class 写法:
class MyComp extends React.Component {
// ...
render() {
return {this.state.hello};
}
}
这种情况下 PropTypes/DefaultProps 使用 ES7 类静态属性提案的写法:
class MyComp extends React.Component {
static propTypes = {
size: React.PropTypes.oneOf(['large', 'small']),
disabled: React.PropTypes.bool
};
static defaultProps = {
size: 'large',
disabled: false
};
// ...
}
如果没有内部状态、方法或引用 refs
,使用 Function 写法:
function MyComp ({ hello }) {
return <div>{hello}div>;
}
这种情况下 PropTypes/DefaultProps 使用 静态属性 的写法:
MyComp.propTypes = {
name: React.PropTypes.string
};
MyComp.defaultProps = {
name: 'jason'
};
static
)constructor
、 getChildContext
、 componentWillMount
、 componentDidMount
、 componentWillReceiveProps
、 shouldComponentUpdate
、 componentWillUpdate
、componentDidUpdate
、 componentWillUnmount
)onClickSubmit
或 onChangeDescription
)renderNavigation
或 renderProfilePicture
)render
方法(必须有返回值)推荐两种写法,一是箭头函数:
class MyComp extends Component {
handleClick = () => {
console.log(this);
}
render() {
return this.handleClick}>Please Click!;
}
}
二是在构造函数中绑定:
class Some extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick = () => {
console.log(this);
}
render() {
return this.handleClick}>Please Click!;
}
}
对于简单的初始化,直接使用 ES7 实例属性提案声明写法:
class MyComp extends React.Component {
state = {
foo: 'bar'
};
// ....
}
对于需要计算后才能初始化的 State,使用构造函数声明写法:
class MyComp extends React.Component {
constructor(props) {
super(props);
this.state = {
foo: 'bar'
};
}
// ....
}
不要对 this.state
赋值,使用 this.setState()
更新 State:
// bad
this.state.foo = 'bar';
this.forceUpdate();
// good
this.setState({
foo: 'bar'
})
属性名采用 camelCase 风格:
<Foo
userName="hello"
phoneNumber={12345678}
/>
如果属性为 true
,可以直接省略:
// bad
true} />
// good
数组中或者遍历中输出相同的 React 组件,属性 key
必需,且不要使用 index
作为 key
,推荐使用唯一ID。
{todos.map(todo => (
))}
React 组件的扩展名使用 .jsx
。
文件名使用 PascalCase 命名(如 MyComp.jsx
),组件名使用和文件名相同的名字。如果组件是一个文件夹,那么使用 index.js
作为入口文件。
对于没有子元素的标签自关闭,对于有多个属性的使用多行书写,并在新行关闭:
<Foo className="stuff" />
<Foo
bar="bar"
baz="baz"
/>
属性值使用双引号,其他都使用单引号。
"bar" /> '20px' }} />
总是在自闭合的标签 />
前加一个空格。不要在JSX 的 {}
引用括号里两边加空格:
<Foo />
<Foo bar={baz} />
将多行的 JSX 标签写在 ()
里,单行可以省略。
render() {
return (
<MyComp className="long body" foo="bar">
<MyChild />
MyComp>
);
}