一篇笔记, 参考官方教程并且加上了很多批注
React.Component 是一个抽象基类, 基本结构:
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
最小配置就是一个render()
函数
当一个 component 加载并且加入 DOM 的时候执行
These methods are called when an instance of a component is being created and inserted into the DOM:
当一个 component 重新渲染的时候执行
An update can be caused by changes to props or state. These methods are called when a component is being re-rendered:
删除时执行
This method is called when a component is being removed from the DOM:
当 render 的时候报错
This method is called when there is an error during rendering, in a lifecycle method, or in the constructor of any child component.
这个函数可以返回以下内容:
<div />
), or a user-defined composite component (<MyComponent />
).ReactDOM.createPortal
.null
. Renders nothing.return test && <Child />
pattern, where test
is boolean.)用于返回一个 DOM 时并且用上某些条件的情况
ReactDOM.findDOMNode(this)
will return null.render()
will not be invoked if shouldComponentUpdate()
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.
render()
这个函数里面也可以返回一个 DOM 数组:
render() {
return [
<li key="A">First item</li>,
<li key="B">Second item</li>,
<li key="C">Third item</li>,
];
}
React V16.2 之后也可以用这个方法
render() {
return (
<React.Fragment>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
</React.Fragment>
);
}
区别就在于不需要提供
key
了
mount
状态之前执行这个函数super(props)
调用父类的方法super(props)
的话, this.props
就会变成undefinedthis.state
setState()
mount
发生的时候立刻执行render()
之前执行render()
不一样, setState()
之后, 不会重复执行一次mount
状态之后执行这个函数subscription
的最佳地点, 当然不要忘记在componentWillUnmount()
注销subscription
setState()
之后, 重复执行一次mount
状态的时候并不会执行这个函数, 也就是说, 初始化的时候并不会执行这个函数这个很容易理解了 有一些情况就是不通过
state
而通过props
来刷新的情况, 就可以在这个函数里面判断新的和旧的 prop 是否相等, 并根据判断结果刷新state
true
, 这个函数会导致render()
刷新false
, 也无法防止子模块的刷新shouldComponentUpdate()
returns false
, then componentWillUpdate()
, render()
, and componentDidUpdate()
props
和state
获取到之前执行state
和props
componentWillReceiveProps()
shouldComponentUpdate()
的返回值相关props
是否改变, 并根据这个结果决定是否发送 http 请求shouldComponentUpdate()
的返回值相关(待补充)
state
的读取就必须要小心, 推荐使用componentDidUpdate()
shouldComponentUpdate()
返回了false
, 否则这个函数的执行一定会重新渲染界面state
中state
修改之后执行this.setState((prevState, props) => {
return {counter: prevState.counter + props.step};
});
this.setState({quantity: 2})
这个函数的执行是异步的, 因此如果有这样的执行:
Object.assign(
previousState,
{quantity: state.quantity + 1},
{quantity: state.quantity + 1},
……
)
最后可能仅仅加了 1
因此如果要改变的状态和历史状态有关, 那么最好使用 updater 函数
this.setState((prevState) => {
return {quantity: prevState.quantity + 1};
});
render()
, 并且忽略shouldComponentUpdate()
的限制render()
, 但是会根据它们的生命周期判断shouldComponentUpdate()
的值props
以及state
进行重新渲染这个是直接给一个模块提供默认的prop
class CustomButton extends React.Component {
// ……
}
CustomButton.defaultProps = {
color: 'blue'
};
……
render() {
return <CustomButton /> ; // props.color will be set to blue
}
但是注意, 不管给任何值, 只要给了值, 就一定会覆盖掉默认值
render() {
return <CustomButton color={null} /> ; // props.color will remain null
}
displayName
这个其实是 debug 的时候方便查看用的
没什么好说的了
this.props.children
这个比较特别,这个包含了所有子标签的 JSXsetState()
来进行修改