React: React. Component Overview
Overview
React. Component是一个抽象基类, 基本结构:
1 | class Greeting extends React.Component { |
最小配置就是一个 render()
函数
The Component Lifecycle
Mounting
当一个component加载并且加入DOM的时候执行
These methods are called when an instance of a component is being created and inserted into the DOM:
Updating
当一个component重新渲染的时候执行
An update can be caused by changes to props or state. These methods are called when a component is being re-rendered:
-
componentWillReceiveProps()
-
shouldComponentUpdate()
-
componentWillUpdate()
-
render()
-
componentDidUpdate()
Unmounting
删除时执行
This method is called when a component is being removed from the DOM:
Error Handling
当render的时候报错
This method is called when there is an error during rendering, in a lifecycle method, or in the constructor of any child component.
Functions
Render()
这个函数可以返回以下内容:
- React elements. Typically created via JSX. An element can either be a representation of a native DOM component (
<div />
), or a user-defined composite component (<MyComponent />
). - String and numbers. These are rendered as text nodes in the DOM.
- Portals. Created with
ReactDOM.createPortal
. null
. Renders nothing.- Booleans. Render nothing.(Mostly exists to support
return test && <Child />
pattern, wheretest
is boolean.)
用于返回一个DOM时并且用上某些条件的情况
几个渲染限制
- When returning null or false,
ReactDOM.findDOMNode(this)
will return null. render()
will not be invoked ifshouldComponentUpdate()
returns false.
使用的原则
The render()
function should be pure, meaning that it does not modify component state, it returns the same result each time it’s invoked, and it does not directly interact with the browser.
render()
一般不要改变state里面的内容, 保证这个函数就做单一的渲染这个事情
If you need to interact with the browser, perform your work in componentDidMount()
or the other lifecycle methods instead. Keeping render()
pure makes components easier to think about.
Fragments
render()
这个函数里面也可以返回一个DOM数组:
1 | render() { |
React V16.2之后也可以用这个方法
1 | render() { |
区别就在于不需要提供
key
了
constructor(props)
mount
状态之前执行这个函数- 可以通过
super(props)
调用父类的方法
- 并且如果不调用
super(props)
的话,this.props
就会变成undefined
- 应该在这个函数里初始化
this.state
- 并且不要在这个函数里使用
setState()
- 当然如果我需要绑定函数, 也没有状态变化的话, 就完全不需接入这个接口了
componentWillMount()
mount
发生的时候立刻执行- 在
render()
之前执行
- 但是和
render()
不一样, **setState()
之后, 不会重复执行一次**
componentDidMount()
mount
状态之后执行这个函数- 对于DOM的一系列init可以放在这个地方
- 进行各类网络请求的最佳地点, 比如AJAX获取数据之类的
- 注册
subscription
的最佳地点, 当然不要忘记在componentWillUnmount()
注销subscription
- 关于subscription
- 就是类似于GQL之类的玩意
- **
setState()
之后, 重复执行一次**
- 上面这个用法的时候一定要注意性能问题
componentWillReceiveProps(nextProps)
- 无论新的和旧的prop是否相等都会执行这个函数
- 另外需要注意的是
mount
状态的时候并不会执行这个函数, 也就是说, 初始化的时候并不会执行这个函数
这个很容易理解了
有一些情况就是不通过
state
而通过props
来刷新的情况, 就可以在这个函数里面判断新的和旧的prop是否相等, 并根据判断结果刷新state
shouldComponentUpdate(nextProps, nextState)
- 在新的prop或者state接收到的时候, 并且在刷新之前执行
- 默认情况下返回
true
, 这个函数会导致render()
刷新 - 另外就算是返回
false
, 也无法防止子模块的刷新 - Currently, if
shouldComponentUpdate()
returnsfalse
, thencomponentWillUpdate()
,render()
, andcomponentDidUpdate()
componentWillUpdate(nextProps, nextState)
- 在新的
props
和state
获取到之前执行
- 因此可以在这儿执行一些update的准备活动
- 当然不要在这里面修改
state
和props
- 如果非要修改的话, 最好使用
componentWillReceiveProps()
- 这个函数的是否执行与
shouldComponentUpdate()
的返回值相关
componentDidUpdate(prevProps, prevState)
- 这个就是在更新时候执行
- 对于一些DOM的处理可以放在这个地方
- 另外可以在这个地方判断一下
props
是否改变, 并根据这个结果决定是否发送http请求 - 这个函数的是否执行与
shouldComponentUpdate()
的返回值相关
componentWillUnmount()
- 当元素销毁的时候执行, 因此适合执行一些善后工作
- 比如计时器的关闭, 网络请求关闭, subscriptions的清理等等
componentDidCatch(error, info)
(待补充)
setState(updater[, callback])
- 修改界面的主要方式
- 最好将这个函数看成一个请求, 因为实现更新可能会有一定的延迟, 也有可能将一系列的更新批次完成
- 正因为不会立刻执行, 对于
state
的读取就必须要小心, 推荐使用componentDidUpdate()
- 除非
shouldComponentUpdate()
返回了false
, 否则这个函数的执行一定会重新渲染界面 - 因此通过一定条件判断是否使用这个函数, 可以避免一些不必要的重新渲染
使用方法
- 第一个参数是个updater function
- 第一个参数也可以直接放一个Obj, 会被自动merge到
state
中
- 第二个参数是一个callback, 当
state
修改之后执行
updater的使用方法
1 | this.setState((prevState, props) => { |
updater的使用方法2
1 | this.setState({quantity: 2}) |
异步执行
这个函数的执行是异步的, 因此如果有这样的执行:
1 | Object.assign( |
最后可能仅仅加了1
因此如果要改变的状态和历史状态有关, 那么最好使用updater函数
1 | this.setState((prevState) => { |
component.forceUpdate(callback)
- 对于当前模块强行调用
render()
, 并且忽略shouldComponentUpdate()
的限制 - 同时也会调用所有子模块的
render()
, 但是会根据它们的生命周期判断shouldComponentUpdate()
的值 - 当然不推荐使用这个方法, 尽可能仅仅通过
props
以及state
进行重新渲染
Class Properties
defaultProps
这个是直接给一个模块提供默认的 prop
1 | class CustomButton extends React.Component { |
但是注意, 不管给任何值, 只要给了值, 就一定会覆盖掉默认值
1 | render() { |
displayName
这个其实是debug的时候方便查看用的
Instance Properties
props
没什么好说的了
this.props.children
这个比较特别,这个包含了所有子标签的JSX
state
- 永远不要直接修改这个词一定要通过
setState()
来进行修改