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
title
andchildren
are props;hasError
is state. But you havetitle
in one type andhasError
andchildren
in another, and you've used the typeIErrorBoundaryProps
where the state type argument is expected.The correct type for
children
in 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...