4自 React 16 起,任何未被错误边界捕获的错误将会导致整个 React 组件树被卸载,从而出现白屏问题
解决办法:基于memo封装wrapMemo组件
1、代码目录
2、ErrorBoundary.js
import React from 'react';
import PropTypes from 'prop-types';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
console.log(error);
// 更新 state 使下一次渲染能够显示降级后的 UI
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// 你同样可以将错误日志上报给服务器
// logErrorToMyService(error, errorInfo);
console.log(error, errorInfo);
}
render() {
if (this.state.hasError) {
// 你可以自定义降级后的 UI 并渲染
// return <h1>Something went wrong.</h1>;
return null;
}
return this.props.children;
}
}
ErrorBoundary.propTypes = {
children: PropTypes.object
};
export default ErrorBoundary;
3、wrapMemo.js
import React, { memo } from 'react';
import ErrorBoundary from "./ErrorBoundary";
const wrapMemo = (func) => {
const Comp = memo(func);
const fn = (props) => {
return (
<ErrorBoundary>
<Comp {...props}></Comp>
</ErrorBoundary>
);
};
fn.displayName = 'fn';
return fn;
};
export default wrapMemo;
?4、app.js
import React from 'react'
import Header from './components/Header';
import Content from './components/Content';
import Footer from './components/Footer';
const App = () => {
return (
<div>
<Header name={'header11111'}/>
<Content />
<Footer />
</div>
)
}
export default App
5、Header.js
import React from 'react'
import wrapMemo from '../common/wrapMemo';
const Header = wrapMemo((props) => {
const { name } = props;
return (
<>
<div>Header</div>
<p>{name}</p>
</>
);
});
export default Header
6、Footer.js
import React, { useState, useEffect } from 'react';
import wrapMemo from '../common/wrapMemo';
const Footer = wrapMemo(() => {
const [data, setData] = useState({});
useEffect(() => {
const data = {};
setData(data);
}, []);
return (
<div>{ data.name.s()}</div>
)
});
export default Footer;
|