React Advanced guides

Agenda

原文地址

  • JSX In Depth
  • Booleans, Null, and Undefined Are Ignored
  • Typechecking With PropTypes
  • Refs and the DOM
  • Context

Agenda

  • JSX In Depth
  • Booleans, Null, and Undefined Are Ignored
  • Typechecking With PropTypes
  • Refs and the DOM
  • Context

JSX In Depth

Props Default to "True"

传递一个没有值的属性,其默认值是true


//is equal





console.log(this.props.autocomplete)
// true


console.log(this.props.autocomplete)
// undefined

Spread Attributes

const Component1 = () => {
  return 
}

const Component2 = () => {
  const props = {firstName: 'Ben', lastName: 'Hector'}
  return ;
}

高效但是混乱

We recommend that you use this syntax sparingly.

String Literals

自动删除行首/末位空格,删除空行

Hello World
Hello World
Hello World
Hello World

Booleans, Null, and Undefined Are Ignored

Booleans(false & true), null, undefined都是合法值


{false}
{null}
{true}

全部 render null

const messages = []

{messages.length && }

number '0'不会被转化为 false

{messages.length > 0 && }

确保在&&前面的是booleans

若要显示‘false & true, null, undefined’,需转换为 string

My JavaScript variable is {String(myVariable)}.

Typechecking With PropTypes

我经常使用的 PropTypes

MyComponent.propTypes = {
  optionalArray: React.PropTypes.array,
  optionalBool: React.PropTypes.bool,
  optionalFunc: React.PropTypes.func,
  optionalNumber: React.PropTypes.number,
  optionalObject: React.PropTypes.object,
  optionalString: React.PropTypes.string,
  optionalSymbol: React.PropTypes.symbol,
}

限制在枚举的数组中

optionalEnum: React.PropTypes.oneOf(['News', 'Photos'])

限制在多个类型中

optionalUnion: React.PropTypes.oneOfType([
    React.PropTypes.string,
    React.PropTypes.number,
    React.PropTypes.instanceOf(Message)
])

限定数组中 value 的类型

optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number)

限定对象中 value 的类型

optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number)

限定数据结构

optionalObjectWithShape: React.PropTypes.shape({
    color: React.PropTypes.string,
    fontSize: React.PropTypes.number
})

shape只能用在对象中

optionalObjectWithShape: React.PropTypes.shape({
  colors: React.PropTypes.shape({
    backgroundColor: React.PropTypes.string.isRequired
})

自定义一个validator,异常情况 return Error 对象

customProp: (props, propName, componentName) => {
    if (!/matchme/.test(props[propName])) {
      return new Error(
        'Invalid prop `' + propName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      )
    }
}

可以用箭头函数

自定义arrayOfobjectOf

customArrayProp: React.PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
  console.log('location', location)
  //location prop
  
  console.log('propFullName', propFullName)
  //propFullName customArrayProp[0]
})

遍历每一个元素

Default Prop Values

会不会报错?

class Greeting extends React.Component {
  static propTypes = {
    name: PropTypes.string.isRequired
  }

  static defaultProps = {
    name: 'Stranger'
  }

  render() {
    return (
      

Hello, {this.props.name}

) } }

propTypes类型检查在defaultProps赋值后进行

Refs and the DOM

The ref Callback Attribute

ref 属性可以接受一个回调函数

并且在组件mounted和unmounted时立即调用

回调函数的参数是该 DOM element,unmounted的时候是 null

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props)
    this.handleFocus = this.handleFocus.bind(this)
  }

  handleFocus() {
    this.textInput.focus()
  }

  render() {
    return (
      
{ this.textInput = input }} />
) } }
class AutoFocusTextInput extends React.Component {
  componentDidMount() {
    this.customTextInput.handleFocus()
  }

  render() {
    return (
       { this.customTextInput = customTextInput }}
      />
    )
  }
}
class CustomTextInput extends React.Component {
  handleFocus() {
    this.textInput.focus()
  }

  render() {
    return (
       { this.textInput = input}
      />
    )
  }
}


Functional components

函数式组件,需要提前声明

function CustomTextInput(props) {
  // textInput must be declared here so the ref callback can refer to it
  let textInput = null

  function handleClick() {
    textInput.focus()
  }

  return (
    
{ textInput = input; }} />
) }

Don't Overuse Refs

Reconciliation

The Diffing Algorithm

Elements Of Different Types


  

这里的是一个完全新的组件,旧的状态都将清除

当根元素类型变化,毁掉旧的树,创建新的树

包含在树里的组件会被卸载,所有状态清空

DOM Elements Of The Same Type

类型相同,只更新属性

只更新 color,不更新 fontWeight

Recursing On Children

  • first
  • second
  • first
  • second
  • third

在末尾添加,前面的不会重新渲染

  • first
  • second
  • third
  • first
  • second

更新所有

  • [slide]
    {:&.bounceIn}

    Keys

    • Duke
    • Villanova
    • Connecticut
    • Duke
    • Villanova

    添加 key,更加高效

    key 只需在兄弟节点中唯一

    Context

    Why Not To Use Context

    如果希望稳定,一定不要用 context。

    这是一个实验性 API,可能会在后续版本中移除

    How To Use Context

    不用 context ,组件结构如下:

    class Button extends React.Component {
      render() {
        return (
          
        )
      }
    }
    
    class Message extends React.Component {
      render() {
        return (
          
    {this.props.text}
    ) } }
    class MessageList extends React.Component {
      render() {
        const color = "purple";
        const children = this.props.messages.map((message) =>
          
        )
        return 
    {children}
    } }

    使用 context传递 props

    class Button extends React.Component {
      render() {
        return (
          
        )
      }
    }
    
    Button.contextTypes = {
      color: React.PropTypes.string
    }
    
    class Message extends React.Component {
      render() {
        return (
          
    {this.props.text}
    ) } }
    class MessageList extends React.Component {
      getChildContext() {
        return {color: "purple"}
      }
    
      render() {
        const children = this.props.messages.map((message) =>
          
        )
        return 
    {children}
    } }

    添加childContextTypes 和 getChildContext

    如果未定义contextTypes,context是一个空对象

    Thanks!

  • 你可能感兴趣的:(React Advanced guides)