Fullstack React Ch5

 5th July 2017 at 10:07am

Intro

这一节写得非常赞,摘录一些在这里。这体现了 Facebook 在设计 React Component 时的一些 核心理念

The goal of a ReactComponent is to

  • render() a ReactElement (which will eventually become the real DOM) and
  • attach functionality to this section of the page

“Attaching functionality” is a bit ambiguous; it includes attaching event handlers, managing state, interacting with children, etc. In this chapter we’re going to cover:

  • render() - the one required function on every ReactComponent
  • props - the “input parameters” to our components
  • context - a “global variable” for our components
  • state - a way to hold data that is local to a component (that affects rendering)
  • Stateless components - a simplified way to write reusable components
  • children - how to interact and manipulate child components
  • statics - how to create “class methods” on our components

render()

  1. render() Returns a ReactElement Tree
  2. The render() function’s job is to provide React a virtual representation of a native DOM component.
  3. render() should return a single child element or
  4. return a falsy value (null or false). (React will render an empty <noscript /> element)
  5. render() should be side-effect free to make the component reusable.

props

PropTypes 做数据校验

PropTypes 是 React 做基本的 数据校验 的机制:

const Component = React.createClass({
  propTypes: {
    name: React.PropTypes.string,
    totalCount: React.PropTypes.number
  },
  // ...
})

可以对 JS 基本类型做校验,也可以对复杂类型(如 React.PropTypes 提供了 function, array, arrayOf 等类型)做校验。同时你也可以写自定义的校验函数。

getDefaultProps() 提供默认值

getDefaultProps() 提供了一种 默认值 的机制:

const Counter = React.createClass({
  getDefaultProps: function() {
    return {get
      initialValue: 1
    }
  },
  // ...
});

此时 <Counter /><Counter initialValue={1} /> 是一样的效果。这种机制可以让使用此 Component 的用户关注少一些细节,又提供了一定的灵活性。

getDefaultProps() 只在 Counter 对象被创建时调用一次。这个 component 的不同实例共享同一份默认值数据。

context

context 机制类似全局变量,大部分情况下是不被推荐使用的。它的原理大概是:父 component 定义并拥有一个 context,context 中的值是由这个父 component 的 state / props 决定的;子 component 显式声明要使用父 component 的 context。此时父 component 的 state / props 一旦变化,会即时更新 context,使用此 context 的子 component 也会被重新渲染。 !! state

Practical guide:

One way that we can mitigate and minimize the complex states is by building our apps with a single stateful component composed of stateless components: components that do not keep state.

Stateless State

stateless state 是一个结合了函数式编程思想的概念。比如下面就是一个使用了 stateless state 的 component(官方叫它 functional components):

const Header = function(props) {
  return (<h1>{props.headerText}</h1>)
}

Header 函数返回的是一个 ReactElement,它的行为跟 class components 中的 render 函数类似。Functional Components 鼓励 重用

children

设想你有一个 component 长这个样子:

class Page extends React.Component {
  render() {
    return (
      <Container>
        <Article headline="An interesting article" />
        <Article headline="Another interesting article" />
      </Container>
    )
  }
}

Conatiner component 并不知道它里面是什么,有几个 Article 等等,你可以用 this.props.children 来指代他们:

class Container extends React.Component {
  render() {
    return (
      <div className="container">
        {this.props.children}
      </div>
    );
  }
}

实际运行时,this.props.children 可能是单个 ReactElement,也可能是多个 ReactElement (以数组形式)。

React 针对 Children 的场景提供了很多工具函数,以提供更编程化的能力:React.Children.map(), React.Children.forEach(), React.Children.toArray()

statics

component 的 statics 函数,就像类的静态函数一样。需要用时看下文档就好,很简单。