新特性快速了解
随着React版本的更新,在v16(16.0-16.3)主要更新的新功能有下面几点:
-
fragments (返回片段类型):
//不需要再把所有的元素绑定到一个单独的元素中了 render() { return [ // 别忘记加上key值 <li key='A'>first item</li>, <li key='B'>second item</li>, <li key='A'>third item</li> ]; } 复制代码
-
error boundaries(处理错误)
v16 使用了一个更有弹性的错误处理策略。默认情况下,如果一个错误是在组件的渲染或者生命周期方法中被抛出,整个组件结构就会从根节点中卸载。这种方式阻碍了被坏数据的展示,然而,却不是很好的用户体验。
对于这种问题,你可以使用errorboundaries(错误边缘)来进行处理,它是专门用来抓取其下子组件错误并展示错误信息的组件。类似于try{}catch(){}语句。
写法可以参考这里error-handling-modal
-
portals (挂载方式)
render() { // React does *not* create a new div. It renders the children into `domNode`. // `domNode` is any valid DOM node, regardless of its location in the DOM. return ReactDOM.createPortal( this.props.children, domNode, ); } 复制代码
-
custom DOM attributes (支持自定义DOM属性)
-
improved server-side rendering (提升服务端渲染性能)
-
reduced file size (减少文件大小)
-
新的生命周期方法
几个特定的新的声明周期方法会被引入,而旧的会被废弃。
componentWillMount
--使用componentDidMount
代替componentWillUpdate
--使用componentDidUpdate
代替componentWillReceiveProps
--使用一个新的方法:static getDerivedStateFromProps
来代替。static getDerivedStateFromProps(nextProps, prevState) { if(nextProps.currentRow === prevState.lastRow) { return null; } return { lastRow: nextProps.currentRow, isCrollingDown: nextProps.curentRow > prevState.lastRow } } 复制代码
这几个旧的生命周期仍然可以用到React 16.4。在React 17里将被彻底移除。
-
新的Context API
新特性重点- new context API
Context API —— 本来它是一个官方推出的、文档化的 API,但开发者们又提醒我们尽量不要用这个 API,因为这个 API 还没完全确定下来,以后可能会再作修改,而且文档尚不完备。不过,作为可以替代 Redux 和 MobX的方法,其表现可圈可点。
React.createContext
方法用于创建一个 Context 对象。该对象包含 Provider 和 Consumer 两个属性,分别为两个 React 组件。Provider
组件。用在组件树中更外层的位置。它接受一个名为 value 的 prop,其值可以是任何 JavaScript 中的数据类型。Consumer
组件。可以在 Provider 组件内部的任何一层使用。它接收一个名为 children 值为一个函数的 prop。这个函数的参数是 Provider 组件接收的那个 value prop 的值,返回值是一个 React 元素(一段 JSX 代码)
具体代码实现如下
:
const InfoContext = React.createContext({
id: 7788,
name: 'circe'
});
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
profile: {
id: 233333,
name: 'Anderson'
}
}
}
render() {
return (
<InfoContext.Provider value={this.state.profile}>
<Wrapper/>
</InfoContext.Provider>
)
}
}
const Wrapper = props => {
return <Detail/>
}
const Detail = props => {
return <NameShow/>
}
const NameShow = props => {
return <InfoContext.Consumer>
{
context => (
<div>
<p>id: {context.id}</p>
<p>name: {context.name}</p>
</div>
)
}
</InfoContext.Consumer>
}
复制代码
界面显示:
id: 233333name: Anderson
可以看到,对比之前数据层层传递的写法,明显写法简洁了很多。
使用时要注意:
- React.createContext 方法接收一个默认值作为参数。当 Consumer 外层没有对应的 Provider 时就会使用该默认值。
- Provider 和 Consumer 必须来自同一次 React.createContext 调用。也就是说 NameContext.Provider 和 AgeContext.Consumer 是无法搭配使用的
- Provider 组件的 value prop 值发生变更时,其内部组件树中对应的 Consumer 组件会接收到新值并重新执行 children 函数。此过程不受 shouldComponentUpdete 方法的影响。
参考文档: