支持返回这五类:React elements, 数组,Fragments,Portal,String/numbers,boolean/null。
class Example extends React.Component {
render() {
return [
<div key="1">first element</div>,
<div key="2">second element</div>,
];
}
}
// 先定一个组件ErrorBoundary
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { error: null, errorInfo: null };
}
componentDidCatch(error, errorInfo) {
// Catch errors in any components below and re-render with error message
this.setState({
error: error,
errorInfo: errorInfo
})
// You can also log error messages to an error reporting service here
}
render() {
// 有错误的时候展示回退
if (this.state.errorInfo) {
// Error path
return (
<div>
<h2>Something went wrong.</h2>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.toString()}
<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
// 正常的话,直接展示组件
return this.props.children;
}
}
class BuggyCounter extends React.Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
componentWillMount() {
throw new Error('I am crash');
}
handleClick() {
this.setState(({counter}) => ({
counter: counter + 1
}));
}
render() {
if (this.state.counter === 5) {
// Simulate a JS error
throw new Error('I crashed!');
}
return <h1 onClick={this.handleClick}>{this.state.counter}</h1>;
}
}
function App() {
return (
<div>
<p>
<b>
This is an example of error boundaries in React 16.
<br /><br />
Click on the numbers to increase the counters.
<br />
The counter is programmed to throw when it reaches 5. This simulates a JavaScript error in a component.
</b>
</p>
<hr />
<ErrorBoundary>
<p>These two counters are inside the same error boundary. If one crashes, the error boundary will replace both of them.</p>
<BuggyCounter />
</ErrorBoundary>
<hr />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
是16版本核心,提升优化的react性能;
(react-call-return npm)插件学习与应用
组件作用是将一些子元素添加到Domtree上且不需要为这些元素提供额外的父节点;
例子:
render() {
return (
<Fragment>
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
</Fragment>
);
}
Fragment官方使用教程
全局变量,不需要向之前一样传递下去;
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
class Toolbar extends React.Component {
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
//添加一下三个生命周期
add:getDerivedstatefromprops;
getsnapshotBeforeUpdate;
componentDidCatch;
//标记一下三个周期为不安全
unsafe:componentwillMount
componentwillUpdate
componentwillReceiveProps
16之前:
<input type="text" ref={element => this.textInput = element} />
16之后
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
render() {
return <input type="text" ref={this.inputRef} />;
}
componentDidMount() {
this.inputRef.current.focus();
}
}
可以在开发阶段开启严格模式发现应用的潜在问题提升应用的健壮性;
1识别出使用不安全生命周期的组件
2对使用string ref进行告警
3对使用findDOMNode进行告警
4探测某些产生副作用的方法
5对使用弃用context API进行警告
function ExampleApplication() {
return (
<div>
<Header />
<React.StrictMode>
<div>
<ComponentOne />
<ComponentTwo />
</div>
</React.StrictMode>
<Footer />
</div>
);
}
是Hmtl5的事件规范之一,它主要目的是用来将鼠标(Mouse)、触摸(touch)和触控笔(pen)三种事件整合为统一的API
onPointerDown
onPointerMove
onPointerEnter
onPointerLeave
onPointerOver
onPointerOu
谷歌插件下载即可,可以检测到组件渲染耗时
import React, { memo } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function Demo(props) {
console.log("render");
return <div>{props.name}</div>;
}
const Demo1 = memo(function Demo(props) {
console.log("render");
return <div>{props.name}</div>;
});
class App extends React.Component {
state = { count: 0 };
handleClick = () => {
this.setState({ count: 1 });
};
render() {
return (
<div className="App">
<h1>Hello Memo</h1>
<button onClick={this.handleClick}>
This is Memo Demo{this.state.count}
</button>
<Demo1 name={"daisy"} />
</div>
);
}
}
在你的函数前面加Memo就可以像PureComponent实现shouldComponentUpdate优化渲染功能。
用于实现动态加载组件
<!--import B from "./B";-->
// 需要用到的时候才加载进来,当然还有预加载更好
const B = lazy(() => import("./B"));
<Suspense fallback={<div>Loading...</div>}>
<TabPanel>
<B />
</TabPanel>
</Suspense>
该生命周期触发条件是组件抛出错误:
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
// 更新state所以下次render可以立刻显示fallback UI
return { hasError: true };
}
componentDidCatch(error, info) {
// You can also log the error to an error reporting service
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
就是不需要包裹consumer,用this.context即可。这个文档需要各位亲好好查查,就是新版context的使用方式,redux的connect原理就是基于它而生。
1.Hook要解决的是状态逻辑复用问题且不会产生jsx嵌套地狱;
2.Hooks只能在函数式组件中使用例如:
import React, { useState } from 'react';
function Example() {
// count表示预设置参数;setCount表示方法,useState(0)设置初始值0
const [count, setCount] = useState(0);
const [ok, setOk] = useState("yes");
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}