Home > database >  What props and interface should I use for this Typescript component?
What props and interface should I use for this Typescript component?

Time:01-29

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.

  1. You've mixed up props and state. Your title and children are props; hasError is state. But you have title in one type and hasError and children in another, and you've used the type IErrorBoundaryProps where the state type argument is expected.

  2. The correct type for children in a React component is ReactNode.

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>
        );
    }
}

Playground link

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...

  • Related