React.memo
类似于PureComponent,对引用类型的数据进行浅比较,即只会比较引用地址是否一致,对地址里的数据不会进行比较。区别就是一个用的class,一个用的function,两种用法比较:
// React.PureComponent
export default class MyPureComponent extends React.PureComponent {
render() {
console.log(this.props);
return (
<p>This is {this.props.arrs.toString()}.</p>
);
}
}
// React.memo
const MyMemoComponent = (props) => {
return (
<p>This is {props.arrs.toString()}.</p>
);
};
export default React.memo(MyMemoComponent);
// app.js
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
arrs: ['1']
};
}
handleChangeArrsValue() {
// MyPureComponent|MyMemoComponent不会重新渲染
const {arrs} = this.state;
arrs.push(Math.random());
this.setState({ arrs });
// MyPureComponent|MyMemoComponent会重新渲染
// const {arrs} = this.state;
// const newArrs = arrs.slice(0).push(Math.random());
// this.setState({ arrs: newArrs });
}
render() {
const { arrs } = this.state;
return(
<button
type="button"
onClick={this.handleChangeArrsValue.bind(this)}
>
点击更新数组值
</button>
<MyPureComponent arrs={arrs} />
<MyMemoComponent arrs={arrs} />
);
}
}
// 参考:https://reactjs.org/docs/react-api.html#reactmemo
复制代码
React.lazy
可以让你能动态渲染组件,最基础的使用就是在组件A渲染完毕之前,用loading效果展示。用法比较简单,其中Suspense
中的fallback
可以设置在LazyComponent
组件渲染完成前你想要展示的内容,比如一个loading效果等。
// LazyComponent.js
import React from 'react';
const LazyComponent = () => {
return (
<p>This is a LazyComponent</p>
);
};
export default LazyComponent;
// app.js
import React, { lazy, Suspense } from 'react';
const LazyComponent = lazy(() => import('./LazyComponent'));
class App extends React.Component {
render() {
return(
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}
}
// 参考:https://reactjs.org/docs/code-splitting.html#reactlazy
复制代码
React.lazy(() => import('./LazyComponent'))
这种写法需要添加babel插件,否则会报错,这里使用的是babel7,只要修改对应.babelrc文件。
{
...
"plugins": [
...
"@babel/plugin-syntax-dynamic-import",
...
}
复制代码
还有一个注意事项官方文档提到的,lazy|Suspense
现在还不能在服务端进行渲染,官方推荐用React Loadable。
Note: React.lazy and Suspense is not yet available for server-side rendering. If you want to do code-splitting in a server rendered app, we still recommend React Loadable. It has a nice guide for bundle splitting with server-side rendering.
static contextType
官方的Context Api在v16.3正式引入,替代了原先的Legacy Context API,在16.6.0版本中增加了contextType,只要将对应的context[如themesContext]赋值给myClass.contextType,这样在任何地方,无论是生命周期还是render方法中都能对其[this.context]进行引用。简单的官方例子。
// theme-context.js
import React from 'react';
export const themes = {
light: {
foreground: '#000000',
background: '#ddd',
color: '#000'
},
dark: {
foreground: '#ffffff',
background: '#666',
color: '#fff'
}
};
export const ThemeContext = React.createContext(
themes.dark
);
// themed-button.js
import React from 'react';
import { ThemeContext } from './theme-context';
class ThemedButton extends React.Component {
render() {
const { props } = this;
const theme = this.context;
return (
<button
{...props}
type="button"
style={{
color: theme.color,
backgroundColor: theme.background
}}
/>
);
}
}
ThemedButton.contextType = ThemeContext;
export default ThemedButton;
// app.js
function Toolbar(props) {
return (
<ThemedButton onClick={props.changeTheme}>
Change Theme
</ThemedButton>
);
}
class TestNewApi extends React.Component {
constructor(props) {
super(props);
this.state = {
theme: themes.light
};
this.toggleTheme = () => {
this.setState(state => ({
theme:
state.theme === themes.dark
? themes.light
: themes.dark
}));
};
}
render() {
return (
<ThemeContext.Provider value={this.state.theme}>
<Toolbar changeTheme={this.toggleTheme} />
</ThemeContext.Provider>
);
}
}
复制代码
这里只是简单的展示了用法,更多的资料可以参考官方提供的文档。
static getDerivedStateFromError()
一个新的生命周期,当组件A抛错误时会执行到该生命周期,修改其错误状态,渲染出对应错误提示的组件B。在生命周期componentDidCatch
也可以设置状态来展示组件B,但是这个功能将会在未来的版本被废除,所以官方建议如果需要设置状态,在getDerivedStateFromError中设置,而不是componentDidCatch
。
同样getDerivedStateFromError
也不支持服务端渲染,在后续版本中可以得到支持,只是现在在16.6.0版本中提前发布该生命周期。
Note: getDerivedStateFromError() is not yet available for server-side rendering. It is designed to work with server-side rendering in a future release. We’re releasing it early so that you can start preparing to use it.