React 有两种组件:class组件 和 函数组件。class组件需要继承 React.Component,用法如下:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
每一个继承 React.Component
的组件,都必须重写 render()
方法。
React建议:不要创建自定义基类组件,使用组合而非继承的方式写组件。
当组件实例被创建并插入 DOM 中时,调用顺序如下:
constructor(props) {
// 1、一定要写这句,否则会出现 this.props 未定义bug。
super(props);
// 2、构造函数是唯一能给state初始化的地方,但不要调用 this.setState() 赋值,
// 会触发render()方法,引起不必要的bug。
this.state = { counter: 0 };
// 3、这里可以绑定组件的 事件处理函数
this.handleClick = this.handleClick.bind(this);
}
// 初始挂载及后续更新时都会被调用,
static getDerivedStateFromProps(props, state)
数据初始化操作
、 网络请求获取数据操作
。当组件的 props 或 state 发生变化时会触发更新。调用顺序如下:
// 初始挂载及后续更新时都会被调用,
static getDerivedStateFromProps(props, state)
此方法仅用于性能优化。返回true,表示组件需要重新渲染;返回false,表示跳过渲染,默认返回值为 true。
// 函数原型
getSnapshotBeforeUpdate(prevProps, prevState)
// 使用实例
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// 我们是否在 list 中添加新的 items ?
// 捕获滚动位置以便我们稍后调整滚动位置。
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// 如果我们 snapshot 有值,说明我们刚刚添加了新的 items,
// 调整滚动位置使得这些新 items 不会将旧的 items 推出视图。
//(这里的 snapshot 是 getSnapshotBeforeUpdate 的返回值)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}
componentDidUpdate(prevProps) {
// 典型用法(不要忘记比较 props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法:
// 函数原型
static getDerivedStateFromError(error)
// 使用示例
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// 更新 state 使下一次渲染显示自定义错误UI
return { hasError: true };
}
render() {
if (this.state.hasError) {
// 你可以渲染任何自定义的 UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
// 函数原型
componentDidCatch(error, info)
// error : 抛出的错误;
// info : 错误的堆栈信息
// 使用示例
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// 更新 state 使下一次渲染可以显示降级 UI
return { hasError: true };
}
componentDidCatch(error, info) {
// "组件堆栈" 例子:
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
logComponentStackToMyService(info.componentStack);
}
render() {
if (this.state.hasError) {
// 你可以渲染任何自定义的降级 UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
class CustomButton extends React.Component {
// ...
}
CustomButton.defaultProps = {
color: 'blue'
};
render() {
return <CustomButton />; // props.color 将设置为 'blue'
}
this.props.children
:特指子组件。详细用法,看这里!setState(updater, [callback])
// 用函数方式:
this.setState((state, props) => {
return { counter: state.counter + props.step };
});
// 用对象方式:
this.setState({ quantity: 2 })
// 函数原型
component.forceUpdate(callback)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。