移动端开发人员闭眼开发了React一段时间后回过头来看文档。留下笔记:
1、渲染组件
以前对于多个地方都会用的组件,选择专门写一个类来封装。其实在一个页面重复使用,或者为了看上去更清晰。可以直接把组件写在一个变量或者一个方法里。
// 函数式组件(注:函数式组件不支持ref)
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
复制代码
2、更新state
this.props 和 this.state 可能是异步更新的,不应该依靠它们的值来计算下一个状态。
// 错误的示范
this.setState({
counter: this.state.counter + this.props.increment,
});
复制代码
// 正确的示范
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
复制代码
3、条件渲染
以前一知半解只会三目运算符
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
""
)}
</div>
);
}
复制代码
其实可以更简洁
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
// 这里有个坑, “falsy” 值(比如数字0),它们依然会被渲染。emptyList 为空数组时,它会打印0
{this.state.emptyList.length && <List datasource={this.state.emptyList} />
}
</div>
);
}
复制代码
或者是阻止渲染
function WarningBanner(props) {
if (!props.warn) {
return null;
}
return (
<div className="warning">
Warning!
</div>
);
}
复制代码
4、Context
Context可以跨层传值,也可以用于多个组件共享属性。但是需要注意的是,要求React版本必须>=16.3(升级之后需要重启)。
import React, { Component } from 'react';
const AJContext = React.createContext('somebody');
function AJView() {
return <AJText />;
}
function AJText() {
return (
<AJContext.Consumer>
{theme => (
<div>
Hi {theme}, there is anjohnlv.
</div>
)}
</AJContext.Consumer>
);
}
export class ContextView extends Component {
render() {
return (
<div>
<AJContext.Provider value="anybody">
<AJView />
</AJContext.Provider>
</div>
);
}
}
复制代码
5、Fragments
Fragments 看起来像空的 JSX 标签:
render() {
return (
<>
<ChildA />
<ChildB />
<ChildC />
</>
);
}
复制代码
但是并不常用,因为目前有些前端工具不支持,如用 create-react-app 创建的项目就不能通过编译。<></>
是 <React.Fragment/>
的语法糖。可以使用<React.Fragment/>
来完成我们期望的操作。
6、Portals
当需要将子节点渲染到父组件以外的 DOM 节点时,我们需要用到Portals。(可实现类似ant-design中Modal的效果)
export class PortalDemoView extends Component {
constructor(props) {
super(props);
this.el = document.getElementById('portalRoot');
}
render() {
return ReactDOM.createPortal(this.props.children, this.el);
}
}
复制代码