반응형

리액트에서 컴포넌트 간 데이터를 주고받는 로직을 구현하는 중 아래와 같은 에러가 발생하여 해결방법을 공유한다.

 

Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<> & Readonly<{}> & Readonly<{ children?: ReactNode; }>'.
Property '' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<> & Readonly<{}> & Readonly<{ children?: ReactNode; }>'

 

부모 컴포넌트에서 자식 컴포넌트로 props를 전달하는 과정에서 발생하였으며, 리액트에서 발생한 에러보다는 타입 스크립트에서 발생한 오류인 것처럼 보였다.

 

우선 나의 상황은 아래와 같다.

 

부모 컴포넌트

 

import { Component } from "react";
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css";
import BoardList from "BoardList";
import Write from "Write";

/**
 * App class
 */
class App extends Component {
    state = {
        isModifyMode: false,
    };

    /**
     * @return {Component} Component
     */
    render() {
        return (
            <div className="App">
                <BoardList isModifyMode={this.state.isModifyMode}></BoardList>
                <Write isModifyMode={this.state.isModifyMode}></Write>
            </div>
        );
    }
}

export default App;

 

자식 컴포넌트

 

import React, { Component } from "react";
import Axios from "axios";
import Table from "react-bootstrap/Table";
import Button from "react-bootstrap/Button";

const Board = ({
    id,
    title,
    registerId,
    registerDate,
    props,
}: {
    id: number;
    title: string;
    registerId: string;
    registerDate: string;
    props: any;
}) => {
    return (
        <tr>
            <td>
                <input type="checkbox" value={id} onChange={props.onCheckboxChange}></input>
            </td>
            <td>{id}</td>
            <td>{title}</td>
            <td>{registerId}</td>
            <td>{registerDate}</td>
        </tr>
    );
};

interface IProps {
    isModifyMode: boolean;
}

/**
 * BoardList class
 * @param {SS} e
 */
class BoardList extends Component {
    /**
     * @param {SS} props
     */
    constructor(props: any) {
        super(props);
        this.setState({
            isModifyMode: props.isModifyMode,
        });
    }

    state = {
        title: "",
        boardList: [],
        checkList: [],
        isModifyMode: false,
    };

    getList = () => {
        Axios.get("http://localhost:8000/list", {})
            .then((res) => {
                const { data } = res;
                this.setState({
                    boardList: data,
                });
            })
            .catch((e) => {
                console.error(e);
            });
    };

    onCheckboxChange = (e: any) => {
        const list: Array<string> = this.state.checkList;
        list.push(e.target.value);
        this.setState({
            checkList: list,
        });
    };

    handleModify = () => {
        if (this.state.checkList.length == 0) {
            alert("수정할 게시글을 선택하세요.");
        } else if (this.state.checkList.length == 1) {
        } else {
            alert("하나의 게시글만 선택하세요.");
        }
    };

    /**
     */
    componentDidMount() {
        this.getList();
    }

    /**
     * @return {Component} Component
     */
    render() {
        const { boardList }: { boardList: any } = this.state;

        return (
            <div>
                <Table striped bordered hover>
                    <thead>
                        <tr>
                            <th>선택</th>
                            <th>번호</th>
                            <th>제목</th>
                            <th>작성자</th>
                            <th>작성일</th>
                        </tr>
                    </thead>
                    <tbody>
                        {boardList.map((v: any) => {
                            return (
                                <Board
                                    id={v.BOARD_ID}
                                    title={v.BOARD_TITLE}
                                    registerId={v.REGISTER_ID}
                                    registerDate={v.REGISTER_DATE}
                                    key={v.BOARD_ID}
                                    props={this}
                                />
                            );
                        })}
                    </tbody>
                </Table>
                <Button variant="info">글쓰기</Button>
                <Button variant="secondary" onClick={this.handleModify}>
                    수정하기
                </Button>
                <Button variant="danger">삭제하기</Button>
            </div>
        );
    }
}

export default BoardList;

 

반응형

 

해결방법

자식 컴포넌트에서 선언한 interface IProps를 Component에 추가해주어야 한다.

즉, 아래와 같이 변경했다.

 

변경 전: class BoardList extends Component

변경 후: class BoardList extends Component<IProps>

 

해결하는데 굉장히 오랜시간이 걸렸는데,, 막상 해결되니까 설명할게 별로 없다.

 

혹시 동일하게 해도 안되시는 분은 댓글로 남겨주세요.

저도 이것저것 다해보고 최종적으로 선택한 대안입니다.

반응형