react v.16的新特性学习

1、Fragment

新版本的render可以返回数组、字符串、react组件、数字、boolean值
v15.x必须要一个标签来包裹
Before v16

return (
        <div>
            <label htmlFor="name">名字:</label>
            <input id="name" type="text" placeholder="请输入名字"/>
            <button>搜索</button>
        </div>
    );

When v16.0.0

return (
    [
        <label htmlFor="name">名字:</label>,
        <input id="name" type="text" placeholder="请输入名字"/>,
        <button>搜索</button>
    ]
);

Now v16.2.0

return (
    <React.Fragment>
       <label htmlFor="name">名字:</label>
       <input id="name" type="text" placeholder="请输入名字"/>
       <button>搜索</button>
    </React.Fragment>
);

片段(fragments) 可以让你将子元素列表添加到一个分组中,并且不会在DOM中增加额外节点。key 是唯一可以传递给 Fragment 的属性

return (
    <dl>
      {props.items.map(item => (
        // 没有`key`,将会触发一个key警告
        <React.Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </React.Fragment>
      ))}
    </dl>
  );

简明写法<>

return (
    <>
       <label htmlFor="name">名字:</label>
       <input id="name" type="text" placeholder="请输入名字"/>
       <button>搜索</button>
    </>
);

DOM Fragment

const select = document.getElementById('select')
const values = [1, 2, 3]
const fragment = document.createDocumentFragment()
values.map(item => {
    const option = document.createElement('option')
    option.value = item
    option.innerHTML = `小明${item}号`
    fragment.appendChild(option)
})
select.appendChild(fragment)

2、Portals

Portals是reactjs16提供的官方解决方案,使得组件可以脱离父组件层级挂载在DOM树的任何位置。
普通情况下,组件的render函数返回的元素会被挂载在它的父级组件上。
然而,有些元素需要被挂载在更高层级的位置。最典型的应用场景:当父组件具有overflow: hidden或者z-index的样式设置时,组件有可能被其他元素遮挡,就可以考虑使用Portal使组件的挂载脱离父组件。
组件的挂载点虽然可以脱离父组件,但组件的事件通过冒泡机制仍可以传给父组件。

<body>
    <div id="bd"></div>
    <div id="modal"></div>
</body>
render(
  <App>
    <SearchBox>
      <Modal>
        <div>模态框</div>
      </Modal>
    </SearchBox>
  </App>,
  document.getElementById('bd'),
  () => {
  console.log(arguments)
})

cl

ass App extends Component{
  constructor(options) {
    super(options)
    this.handleClick = this.handleClick.bind(this)
  }
  handleClick() {
    alert('react component tree propagation!')
  }
  render() {
    return <div className="app" onClick={this.handleClick}>
      {this.props.children}
    </div>
  }
}
class Modal extends Component {
    constructor(options) {
      super(options)
    }
    render() {
      return createPortal(this.props.children, document.getElementById('modal'))
    }
  }
<div id="bd">
    <div class="app">
        <label for="name">名字:</label>
        <input type="text" id="name" placeholder="请输入名字">
        <button>搜索</button>
    </div>
</div>
<div id="modal">
    <div>模态框</div>
</div>
<App>
    <div className="app" onClick=bound handleClick()>
        <SearchBox>
            <labelhtmlFor="name">名字:</label>
            <inputid="name"type="text"placeholder="请输入名字"></input>
            <button>搜索</button>
            <Modal>
                <ReactPortal target=HTMLDivElement{…}>
                    <div>模态框</div>
                </ReactPortal>
            </Modal>
        </SearchBox>
    </div>
</App>

Before portals

ReactDom.render(reactChild, container, callback)

ReactDom.unmountComponentAtNode(container)


ReactDom.unstable_renderSubtreeIntoContainer(
    context,
    reactChild,
    domNode,
    callback
)

ReactDom.unmountComponentAtNode(container)


render: ReactMount._renderSubtreeIntoContainer(null, reactChild, container, callback )

unstable_renderSubtreeIntoContainer: ReactMount._renderSubtreeIntoContainer(context, reactChild, container, callback)

3、Error Boundaries

之前react在渲染过程中或者是生命周期内出现了致命的错误,react会从根组件上把所有的组件都卸载下来,以防止展现错误的数据,但这不是最好的用户体验。React 16修复了这一点,引入了Error Boundary的概念,中文译为“错误边界”,当某个组件发生错误时,我们可以通过Error Boundary捕获到错误并对错误做优雅处理。(注:它并不能捕获runtime所有的错误,比如组件回调事件里的错误,可以把它想象成传统的try-catch语句)

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }
// 新增了componentDidCatch这个生命周期函数,它可以捕获自身及子树上的错误并对错误做优雅处理,包括上报错误日志、展示出错提示,而不是卸载整个组件树。
  componentDidCatch(error, info) {
    // 错误代理组件的展示与否
    this.setState({ hasError: true });
    // 在这里我们可以对错误进行记录
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // 在这里我们可以书写自己想要展示的ui组件
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

上面的组件是当页面中有错误时我们想要展示的效果,具体用法如下:

render(){
  return (
    <div>
      <ErrorBoundary>    // 外层组件我们定义的错误组件
        <Profile user={this.state.user} />     // 内层组件是我们将要监视的自定义组件
      </ErrorBoundary>
      <button onClick={this.onClick}>Update</button>
    </div>
  )
}

这个组件能够不仅仅能够监听到本组件的错误,连同它下面的子组件的错误也可以监听到

不能捕获的错误

  • 事件处理
  • 异步回调
  • 服务端渲染
  • error boundary组件自身抛出的错误(只能由父级捕获)

react遇到未捕获的错误会怎么办

对 React16 来说,一个未捕获的错误会导致整个应用不能被挂载

4、setState传入null时不会再触发更新

之前的setState不管传入什么只要调用了这么方法就会渲染

selectCity(e){
  const newValue = e.target.value;
  this.setState((state)=>{
    if(state.city===newValue){
      return null;
    }
    return {city:newValue}
  })
)

5、v16.0支持自定义的dom属性

之前的版本对于自定义属性react会在属性前加上data-**来进行处理,现在对于部分属性去除了这种写法,拥抱了原生dom,这样可以减少react的代码,提升了性能

6、其他

更好的服务器端渲染:React 16的SSR被完全重写,新的实现非常快,接近3倍性能于React 15,现在提供一种流模式streaming,可以更快地把渲染的字节发送到客户端。

react v16采用了最新的技术“Fiber.”

React Server Side Rendering 解决 SPA 应用的 SEO 问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值