reactjs - 在 React 中的 try 和 catch 块中呈现相同的组件,而不会失去 ReactJS 中的字段焦点
问题描述
我正在使用一个特定的组件,ReactJS
有时它可能会抛出一些错误,所以我需要逐try-catch
块包装它。我的问题是,当它抛出错误时,我仍然需要渲染组件并向用户显示错误,因此我将错误传递给组件,就prop
好像它被抛出一样。看这个示例代码:
myComponent = (error, data) => { /*render component*/}
renderComponent = () => {
try {
/*THE CODE WHICH MAY THROW ERRORS
BUT MAY ALSO RECEIVE DATA WITHOUT PROBLEM*/
return this.myComponent(undefined,data); //if everything is fine
} catch (e) {
return this.myComponent(e,undefined);
}
render {
return ({this.renderComponent()});
}
这个结构的一切都很好,除了一件事就是每次发生一些错误时整个组件都会重置,这是合乎逻辑的,因为我们正在渲染整个另一个组件(尽管它看起来相同)但是它失去了文本字段和滚动的焦点再次起来等等。
我试图把data
它们error
都state
设置在里面renderComponent
,我会myComponent
单独调用并传递状态,但无论如何我必须在setState
里面使用,render
所以它会导致你知道的问题。
所以我想问你,你对这个案子有什么想法。我不知道一些 React 功能吗?
谢谢
解决方案
从 React 16 开始,有一个名为 的新组件生命周期componentDidCatch
,它基本上是组件的 try-catch。
使用此生命周期,您可以捕获特定组件的错误,因此只有组件的子树会中断而不是整个应用程序 - 您可以根据状态呈现不同的内容。
你可以在这里阅读更多关于它的信息。
在您的情况下,您可以执行以下操作:
class TryCatchComponent extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: undefined, errorInfo: undefined };
}
componentDidCatch(error, errorInfo) {
this.setState({ hasError: true, error, errorInfo });
}
render() {
const { hasError, ...errorProps } = this.state;
if (hasError) {
const { fallback: FallbackComponent } = this.props;
return <FallbackComponent {...errorProps} />;
}
return this.props.children;
}
}
const SomeErrorDisplayComponent = ({ error, errorInfo }) => (
<div>{error} or {errorInfo}</div>
);
const SomeComponent = () => (
<TryCatchComponent fallback={SomeErrorDisplayComponent}>
<ComponentThatMightCrashSometime />
</TryCatchComponent>
);
推荐阅读
- javascript - 隐藏文件上传按钮但显示文件名?
- livecode - 如何编写一个按钮,在 livecode 中保存用户的网站浏览历史
- docxtemplater - Docxtemplater - 循环迭代之间的换行符
- javascript - 如何在javascript中的相同键中合并相似的键值
- google-apps-script - 是否有一个日期函数,我可以通过它提取天数,然后从当前日期中减去它们?
- perl - Perl - 如何在循环内的哈希中添加行?
- ssas - 案例语句 (MDX) 中计算成员的空值
- python - Python游戏的排行榜系统
- android - 如何将 JSON 元素输出到 Kotlin?
- wpf - XamlWriter 图像序列化问题(InvalidOperationException:必须设置属性“UriSource”或属性“StreamSource”。)