[蹭热度系列]React的一些新特性

React 16其实已经出来了大半年了,作为一个前端从业者,深深为自己的技术迟钝感到愧疚。
最近同事讨论的比较多,好奇心驱使下看了下react的文档,现学现卖,分享如下:(示例代码大部分摘抄自React Posts, 原文链接)

1. Fragment

Fragment 是 16.0加入的新特性,在16.2中获得了升级。
在之前的React中,如果我们要在一个Component里面render诸如以下的view

Some text.

A heading

More text.

Another heading

Even more text.

那么我们只能用下面的方法:

render() {
  return (
    
Some text.

A heading

More text.

Another heading

Even more text.
); }

这样导致的问题是,无论我们需不需要,render出的真正的HTML DOM上会多出一个

或者
为了解决这个问题,React16.0提供了在render方法中返回array的功能,现在代码可以写成这样:

render() {
 return [
  "Some text.",
  

A heading

, "More text.",

Another heading

, "Even more text." ]; }

然而我们还是不满意,这个写法太不JSX了,所以提供了Fragment这个Component来解决问题(所以你需要import {Fragment} from 'react'啦)

render() {
  return (
    
      Some text.
      

A heading

More text.

Another heading

Even more text.
); }

还有更简单的写法(为了编译通过你可能需要一些babel的支持)

render() {
  return (
    <>
      Some text.
      

A heading

More text.

Another heading

Even more text. ); }

这样我们真正render出的HTML DOM结构里就不存在不需要的

或者


[蹭热度系列]React的一些新特性_第1张图片
不用 Render出的DOM
[蹭热度系列]React的一些新特性_第2张图片
使用 Render出的DOM

2. Render Props

Render Props可以作为一种新的HOC的写法(见下例),官方给的例子是一个track鼠标位置的component和一个show图片的component:

class Cat extends React.Component {
  render() {
    const mouse = this.props.mouse
    return (
      
    );
  }
}

class MouseWithCat extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      
{/* We could just swap out the

for a here ... but then we would need to create a separate component every time we need to use it, so isn't really reusable yet. */}

); } } class MouseTracker extends React.Component { render() { return (

Move the mouse around!

); } }

定义了MouseWithCat这样一个Component来 Handle Mouse Tracking 这一事件,把track到的x,y坐标放到下一层Cat的mouse这个props上,这是我们之前的一种写法。

现在拥有了Render Props后,我们可以这样写:

class Cat extends React.Component {
  render() {
    const mouse = this.props.mouse;
    return (
      
    );
  }
}

class Mouse extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseMove = this.handleMouseMove.bind(this);
    this.state = { x: 0, y: 0 };
  }

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  }

  render() {
    return (
      
{/* Instead of providing a static representation of what renders, use the `render` prop to dynamically determine what to render. */} {this.props.render(this.state)}
); } } class MouseTracker extends React.Component { render() { return (

Move the mouse around!

( )}/>
); } }

注意Mouse的Render方法中调用的this.props.render, 和我们在MouseTracker中传给Mouse的render方法。
代码展开一下,实际上是我们在Mouse的render方法中调用了我们给Mouse.props传递的render方法,这个render方法接受一个mouse参数,并且返回一个Cat Component, 这个Cat Component接受mouse这个参数,并且在鼠标显示的位置显示一张图片。

使用这个特性的好处很明显,我们不需要MouseWithCat这个Component了,现在Mouse和Cat是两个独立的component,而且我们可以给Mouse传入其他的render参数,比如()}>,而不用再创建一个MouseWithDog

但这个特性其实和这种写法效果相似:

const withMouse = (Component) => ({mouse}) {
  //some code
  return 
}

调用的时候我们先创建一个MouseWithCat变量:

const MouseWithCat = withMouse(Cat);


在效果上来说,都把Mouse和Cat这两个Component解绑了,但有了render props支持后,写法更简洁了。
另外withMouse这个Higher Order Component,也可以使用Render Props:

function withMouse(Component) {
  return class extends React.Component {
    render() {
      return (
         (
          
        )}/>
      );
    }
  }
}

Render Props的render和我们Component的render是两个不同的东西,不要弄混
了。实际上,只是这种写法叫做Render props, 这里只是为了方便理解起了个名字叫render, 我们还可以叫它abc,在Component中调用的时候使用this.props.abc

叫children也可以。

 (
  

The mouse position is {mouse.x}, {mouse.y}

)}/>

再简化:


  {mouse => (
    

The mouse position is {mouse.x}, {mouse.y}

)}

这就是一种FACC(Function As Child Component)了

你可能感兴趣的:([蹭热度系列]React的一些新特性)