用生命谱写代码的赞歌

0%

React 常用 API

React 相关 API

本文介绍了 React 一些常用的 API ,详情访问 React 官方文档

render

  • ReactDom.render(html|react组件, Dom元素)
    • html 或 react 组件外部只能被一层标签包裹
  • render() {return (html|组件)}

jsx 语法

  • 碰到 < 用 html 语法解析,碰到 { 用 js 语法解析
  • DOM 节点属性 class 改为 classNamefor 改为 htmlFor
  • 注释采用{/* */}
  • 标签 style 属性写法:
    1
    style={{fontSize: 50px, display: block}}
    • 其中大括号中内容为 js 对象,对象的属性名不能是 font-size
    • -不符合 js 变量命名规范
    • 可改写为 var s = {fontSize: 50px, display: block}style={s}
  • render() {} 函数中可以自定义变量保存 html 代码

    html 代码中的 map 函数需要用大括号包裹, map 函数内部箭头函数的函数体 不能用{}包裹,否则会冲突,可以不包裹或者 用()包裹

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    render() {
    /* map内部的箭头函数函数体不能用{}包裹,否则会冲突,可以不包裹或者改用()包裹 */
    const items = <ul>
    {this.state.items.map((item, i) => <li key={i} onClick={() => this.handleRemove(i)}>{item}</li>)}
    </ul>
    return (
    <div>
    <input type="text" value={this.state.inputValue} onChange={this.handleValue} onKeyUp={this.handleAdd}/>
    {items}
    </div>
    )
    }

react 分发 html

将 html 代码保存在 button 变量中,然后在父组件 Todo 的子组件 List 上添加自定义 html 属性 button={button}

1
2
3
4
5
6
7
8
9
10
// 父组件Todo渲染
render() {
const button = <button>点击变身</button>
return (
<div>
<Input submitFn={this.submitFn.bind(this)}/>
<List todos={this.state.todos} deleteFn={this.deleteFn.bind(this)} button={button}/>
</div>
)
}

在子组件中使用 this.props.button 接收传过来的 html 代码,可以使用 {this.props.button} 渲染

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 子组件List
render() {
const data = this.props.todos
const button = this.props.button

return (
<ul style={{marginTop: '10px', fontSize: '20px', lineHeight: '30px'}}>
{button}
<ReactCSSTransitionGroup
component="div"
transitionName="example"
transitionAppear={true}
transitionEnterTimeout = {500}
transitionLeaveTimeout = {300}
transitionAppearTimeout = {500}
>
{data.map((item, index) => {
return <li key={index} onClick={this.clickHandler.bind(this, item.id)}>{item.text}</li>
})}
</ReactCSSTransitionGroup>
</ul>
)
}

组件中自定义函数的形式

组件中自定义函数可以分为普通函数和箭头函数,两者均可,如果都是命名函数,普通函数反倒简便一些

二者有一点区别:箭头函数自动绑定 this 指向组件,普通函数的 this 指向为 null ,如果使用箭头函数,在 html 标签内调用函数是不必绑定 this ,否则需要使用 .bind(this) 绑定 this 指向,或者采用箭头函数的调用形式,由于 constructor 内部 .bind(this) 无法传参,所以在有参数的情况下尽量使用箭头函数传参

html 标签属性中函数的调用形式,分为两种情况:

  1. 在 render 函数的 html 标签属性中调用组件内部 普通函数 需要绑定 this 指向,否则组件中的函数内部 this为 null ,也可以采用箭头函数的调用形式
  2. 如果调用组件内部的 箭头函数 , html 标签的属性中调用函数的形式不必绑定 this ,普通函数和箭头函数调用形式均可
  3. html 标签属性中函数调用可以使用箭头函数的形式,箭头函数不传参使用 () => this.clickHandle(),箭头函数传参可以使用 () => this.clickHandler(a, b),其中第一个括号中均不需要写东西,除非需要传递鼠标事件
  4. 如果组件内部函数需要用到鼠标事件,例如 handleChange(e) { console.log(e.target.value) },那么 html 标签属性中可以使用普通函数调用形式 this.handleChange 或者 this.handleChange.bind(this),也可以说使用箭头函数调用形式 (e) => this.handleChange(e)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Hello extends React.Component {
render() {
var arr = ['aa', 'bb', 'cc']
return (
<div>
<p onClick={this.clickHandler.bind(this)}>123</p>
<p style={{fontSize: 50px, display: block}}>345</p>
<ul>
{arr.map(function(item, index) {
return <li key={index}>{item}</li> // 必须使用大括号包裹item返回变量的值(aa, bb, cc), 否则只返回item这个单词. 同理index也要使用大括号包裹, 设置属性key是为了配合React的diff算法提高渲染效率
})}
</ul>
</div>
)
}
// 普通函数
clickHandler(event) {
event.preventDefault() // 阻止默认行为
this.setState = {} // React组件中普通函数内的this为null, 所以需要在绑定事件的时候使用 .bind(this) 传入this, 方便后续使用
console.log(Date.now())
}
// 箭头函数
clickHandler = e => {
e.preventDefault()
this.setState = {}
}
}

生命周期函数

  • 推荐在构造函数中定义state
1
2
3
4
5
6
constructor(props) {
super(props)
this.state = {
userInput: ''
}
}

Refs and the DOM

Use the ref callback to store a reference to the text input DOM element in an instance field (for example, this.textInput).

使用ref回调函数存储一个实例字段(例如textInput)对input文本框的引用

1
<input type="text" ref={input => (this.theInput = input)} value={this.state.userInput} onChange={this.handleChange.bind(this)}/>
  • ref属性
    • 必须是一个回调函数
    • this.refs.textInput 已经过时,未来会被移除
    • Arrow function should not return assignment –> 箭头函数不能返回赋值语句,需要用()包裹
    • 箭头函数的函数体如果只有一行,可省去大括号,表示直接返回结果

事件监听与处理

  • 事件参数(a, b, c, d)
    • 如果传过来的参数够四个,则显示传过来的参数
    • 少一个则表示 Proxy 对象
    • 少两个第二个参数表示 Event 事件对象
    • 比如 handleClick(a, b, c, d)
  • 组件中自定义的箭头函数传参表示直接执行,添加事件处理时需要用空箭头函数包裹起来传参
  • 普通函数传参时最好使用 .bind(this, ...) ,否则this指向不明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 演示错误添加监听事件
componentWillMount() {
window.addEventListener('resize', this.handleResize)
}
componentDidMount() {
// 1.在已经插入到真实DOM节点之后,注册窗体改变大小的事件监听
// 3.用Ajax发起数据请求的操作也要在componentDidMount方法里面去调用
window.addEventListener('resize', this.handleResize)
}
componentWillUnmount() {
// 2.在组件将要被卸载的时候移除监听事件,防止对其他组件的影响
window.removeEventListener('resize', this.handleResize)
}
handleResize = (e) => {
console.log(window.innerWidth)
}

受控表单

  • React 中写死 value 值的表单永远无法改变 value 值
  • this.refs (已过时)获取 dom 元素必须要在 componentDidMount 方法里面或者之后的生命周期函数中使用
  • 受控表单不能设置固定的 value ,否则报错,必须用 onChange 事件改变 value
1
2
3
4
5
6
7
8
<!-- 受控表单 -->
<input type="text" ref={(input) => (this.textInput = input)} value={this.state.userInput} onChange={this.handleChange.bind(this)}/>
<!-- React中写死value值的表单永远无法改变value值 -->
<input type="text" value="hello"/>
<!-- 非受控表单组件里面输入框值改变不受react控制 -->
<input type="text" ref={(input) => (this.textInput2 = input)}/>
<!-- 普通表单 -->
<input type="text">

组合组件

只用存在嵌套关系就是组合组件

  • 组合组件通过 this.props.items 传递属性
  • 必须要用 PropTypes 校验属性
  • 最新 API , PropTypes 从prop-types包引入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React from 'react'
import PropTypes from 'prop-types'

class TodoList extends React.Component {
static propTypes = {
items: PropTypes.any
}
render() {
let createItem = (item) => {
return <li key={item.id}>{item.text}</li>
}
return <ul>{this.props.items.map(createItem)}</ul>
}
}

属性校验

最新 API 通过 prop-types 导入PropTypes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import React from 'react'
import PropTypes from 'prop-types'

export default class CheckProps extends React.Component {
// 初始化props属性值
static defaultProps = {
paly: false,
loop: '对不对'
}
constructor(props) {
super(props)
// 设置初始状态(state只能通过this.setState({})改变)
this.state = {

}
}
static propTypes = {
play: PropTypes.bool.isRequired,
loop: PropTypes.string
}
render() {
return (
<div>
属性校验{this.props.loop}
</div>
)
}
}

context 特性

  • 在父组件中需要一个静态属性和一个方法

    1. 通过静态属性校验传递给子孙组件的属性
      1
      2
      3
      4
      static childContextTypes = {
      color: PropTypes.string,
      age: PropTypes.number
      }
    2. 父组件通过下面方法向子孙组件传递属性
      1
      2
      3
      4
      5
      6
      getChildContext() {
      return {
      color: 'pink',
      age: 12
      }
      }
    3. 在子孙组件里校验父组件传递过来的属性
      1
      2
      3
      static contextTypes = {
      color: PropTypes.string
      }
  • this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点。

  • this.props.children 表示某个组件所包含的所有子节点

  • React.Children 是顶层API之一,为处理 this.props.children 这个封闭的数据结构提供了有用的工具。

    1. 对应方法 React.Children.map
      1
      2
      3
      React.Children.map(this.props.children, function (child) {
      return <li>{child}</li>;
      })
    2. React.Child.forEach
      1
      2
      3
      React.Children.forEach(this.props.children, function (child) {
      return <li>{child}</li>
      })
    3. React.Child.count & React.Child.only

显示隐藏组件的动画效果

  • 使用 npm 包 –> react-addons-css-transition-group
  • 使用 <ReactCSSTransitionGroup>显示/隐藏组件</ReactCSSTransitionGroup>
  • 其中 component='div' 表示是指将 {items} 外面默认包裹的 span 标签替换成 div 标签
1
2
3
4
5
6
7
8
9
10
<ReactCSSTransitionGroup
component = 'div'
transitionName = 'example'
transitionAppear = {true}
transitionEnterTimeout = {500}
transitionLeaveTimeout = {300}
transitionAppearTimeout = {500}
>
{items}
</ReactCSSTransitionGroup>
  • css文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/* -enter是进入时候的初始状态 */
.example-enter {
opacity: 0.01;
}
/* -enter-active是进入时候的结束状态 */
.example-enter.example-enter-active {
opacity: 1;
transition: opacity .5s ease-in;
}

.example-leave {
opacity: 1;
}

.example-leave.example-leave-active {
opacity: 0.01;
transition: opacity 300ms ease-in;
}

.example-appear {
opacity: 0.01;
}

.example-appear.example-appear-active {
opacity: 1;
transition: opacity .5s ease-in;
}