如何解决关于 componentDidCatch 中 setState 的未来弃用警告
原始问题:如果在渲染阶段发生多个错误,如何避免在错误边界内压制其中一些错误?
我的困惑有两个方面:
-
componentDidCatch
应该在提交阶段被调用,并且明确允许副作用。我原以为它在以下示例中为 would only fire once,但它会触发两次。这实际上很有帮助,因为它允许暂时将其用作修复程序,但我仍然想了解原因。 -
react docs 状态下的注释
如果出现错误,您可以通过调用 setState 使用 componentDidCatch() 呈现后备 UI,但这将在未来版本中弃用。改用静态 getDerivedStateFromError() 来处理回退渲染。
这使我将来能够想到的存储多个错误的唯一解决方案无效。
遗憾的是,getDerivedStateFromError
does not have access to state。
以下只是演示当前行为的示例。当在 setState
中取消注释 componentDidCatch
时,我得到了一个可行的解决方案,但是遇到了上述问题。
let countStatic = 0;
let countInstance = 0;
let actualThrows = 0;
const errorComponentGenerator = n => () => { actualThrows++; throw n; };
const One = errorComponentGenerator(1);
const Two = errorComponentGenerator(2);
class Boundary extends React.Component {
state = { hasError: false,errors: [] };
errors = [];
static getDerivedStateFromError(error) {
// expected: two times
console.log('getDerivedStateFromError called')
countStatic++;
return { hasError: true,error };
}
componentDidCatch(error,errorInfo) {
// expected: once,got twice
console.log('componentDidCatch called')
countInstance++;
// Would help,but is discouraged by react docs
// this.setState(state => ({ hasError: true,errors: [...state.errors,error] }));
this.errors.push(error);
}
render() {
if (this.state.hasError)
return (
`static: ${countStatic},instance: ${countInstance},actual: ${actualThrows}\n`
+ `Errors - length: ${this.errors.length}\n`
+ `${JSON.stringify(this.errors)}`
);
return (
<React.Fragment>
<One />
<Two />
</React.Fragment>
);
}
}
const boundaryInstance = React.createRef();
ReactDOM.render(<Boundary ref={boundaryInstance} />,document.getElementById('app'));
setTimeout(
() => console.log(
`afterwards instance: ${countInstance}\n`
+ `${JSON.stringify(boundaryInstance.current.errors)}`
),2000
);
div { white-space: pre-wrap; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
PS:我现在忽略了弃用警告,并采用了“很好用”的策略,但这不是一件好事。也许弃用警告只是意味着“不要更改在 componentDidCatch
中切换到回退的状态”?我想我会看到,当弃用发生时......
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。