I am trying to make an error catcher in Typescript, using ErrorBoundary component. Frankly, I don't understand, what props and interface properties I should use to achieve the same goal as represented in the task from the ZTM course, which I'm taking right now. The original task is in Javascript, however my goal is to make the same app in Typescript, without using any type.
There is my render() method with a custom ErrorBoundary tag, which supposedly should catch errors, when those occur in my CardList component. The code for render() is below:
render() {
const { robots, searchfield } = this.state;
const fileteredRobots = robots.filter(robot => {
return robot.name.toLowerCase().includes(searchfield.toLowerCase())
})
return !robots.length ?
<h1>Loading</h1> :
(
<div className='tc'>
<h1 className='f1'>RoboFriends</h1>
<SearchBox title='search box' searchChange={this.onSearchChange}/>
<ErrorBoundary title='error catcher'>
<Scroll title='scrolling'>
<CardList title='list of robot cards' robots={fileteredRobots} />
</Scroll>
</ErrorBoundary>
</div>
);
}
Error, which occur in this code block, says the following:
Type '{ children: Element; title: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<ErrorBoundary> & Readonly<{ title: string; }>'.
Property 'children' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<ErrorBoundary> & Readonly<{ title: string; }>'.ts(2322)
The code for component ErrorBoundary from ErrorBoundary.tsx is below:
import { Component } from "react";
interface IErrorBoundaryProps {
hasError: boolean;
children?: JSX.Element | JSX.Element[];
}
class ErrorBoundary extends Component<{title:string}, IErrorBoundaryProps> {
constructor(props: {title:string}) {
super (props)
this.state = {
hasError: false,
}
}
render () {
if (this.state.hasError) {
return <h1>Ooops. That is an Error</h1>
}
return this.state.children
}
}
export default ErrorBoundary
I fixed some errors from ErrorBoundary component, however I still get an error above in my App.tsx render() method.
My main question is: how to fix the error, that occured in my render() method?
CodePudding user response:
There are a couple of things going on here.
You've mixed up props and state. Your
titleandchildrenare props;hasErroris state. But you havetitlein one type andhasErrorandchildrenin another, and you've used the typeIErrorBoundaryPropswhere the state type argument is expected.The correct type for
childrenin a React component isReactNode.
Here's a trimmed-down version without errors:
import React, { Component, ReactNode } from "react";
interface IErrorBoundaryProps {
title: string;
children?: ReactNode;
}
interface IErrorBoundaryState {
hasError: boolean;
}
// This one is props −−−−−−−−−−−−−−−−−vvvvvvvvvvvvvvvvvvv
class ErrorBoundary extends Component<IErrorBoundaryProps, IErrorBoundaryState> {
// This one is state −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^
constructor(props: { title: string }) {
super(props);
this.state = {
hasError: false,
};
}
render() {
if (this.state.hasError) {
return <h1>Ooops. That is an Error</h1>;
}
return this.props.children; // ** Use `props` here
}
}
class Example extends Component {
render() {
return (
<ErrorBoundary title="error catcher">
<div>Error stuff here</div>
</ErrorBoundary>
);
}
}
Also, note that your ErrorBoundary component isn't an error boundary yet, because it doesn't implement static getDerivedStateFromError() or componentDidCatch(), but I'm guessing you were going to add that later...
