You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React列表组件实现异常及TypeScript编译报错求助

问题:React客户端渲染物品列表报错及代码问题

我正在编写一个简单的React客户端,用来向服务器发送消息并接收物品列表,但在实现列表渲染后出现了问题。之前未显式处理响应和Mlist组件时,数据收发正常,现在出现TypeScript报错,同时列表渲染逻辑也有问题。

代码如下

import React, { Component, ReactNode } from "react";
import "./CommentPage.scss";
import axios from 'axios';
import { Message } from "@material-ui/icons";
import { Box } from "@material-ui/core";


export class CommentPage extends Component<any, any> {
    public render(): ReactNode {
        return (
            <div>
                <Form />
                <Mlist />
            </div>
        )
    }
}

interface message {
    name: string,
    value: string
}
let data: message[] = [{ name: "a", value: "b" }]

class Form extends Component<{}, { name: string, message: string }> {
    constructor(props: {}) {
        super(props);
        this.state = { name: '', message: '' };

        this.handleChangeName = this.handleChangeName.bind(this);
        this.handleChangeMess = this.handleChangeMess.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChangeName(event: React.ChangeEvent<HTMLInputElement>) {
        this.setState({ name: event.target.value, message: this.state.message });
    }

    handleChangeMess(event: React.ChangeEvent<HTMLInputElement>) {
        this.setState({ name: this.state.name, message: event.target.value });
    }

    handleSubmit(event: React.FormEvent<HTMLFormElement>) {
        axios.post('http://localhost:8080/addComment', {
            author: this.state.name,
            comment: this.state.message
        }).then(r => {
            axios.get('http://localhost:8080/allComments').then(r => {
                r.request.items.map((item: message) => (data.push(item)));
            })
        }).catch(err => {
            alert(err)
        })
        this.setState({ name: this.state.name, message: '' });
        event.preventDefault();
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <label>
                    Name
                    <input type="text" value={this.state.name} onChange={this.handleChangeName} />
                    Message
                    <input type="text" value={this.state.message} onChange={this.handleChangeMess} />
                </label>
                <input type="submit" value="Submit" />
            </form>
        );
    }
}

class Mlist extends Component<{}, {}> {
    render() {
        return (
            <p>{data.map((m) => (
                <li>{m.name}</li>
            ))}</p>
        );
    }
}

报错信息

TypeScript error in /Users/user/IdeaProjects/namep/front/itmo-hw3/node_modules/@types/babel__traverse/index.d.ts(68,50):
']' expected.  TS1005

    66 | }
    67 | 
  > 68 | export type ArrayKeys<T> = keyof { [P in keyof T as T[P] extends any[] ? P : never]: P };
       |                                                  ^
    69 | 
    70 | export class Scope {
    71 |     constructor(path: NodePath, parentScope?: Scope);

解决方案

1. 解决TypeScript版本报错

这个错误是因为当前使用的TypeScript版本不支持映射类型中的as条件子句(该语法在TypeScript 4.1及以上版本才支持),而@types/babel__traverse依赖了这个语法。

升级TypeScript版本:

# npm
npm install typescript@latest --save-dev

# yarn
yarn add typescript@latest --dev

2. 修正React组件逻辑问题

你的代码存在两个核心问题:全局变量无法触发组件重渲染、axios响应数据获取错误。

修改后的完整代码(采用状态提升,父组件管理列表状态):
import React, { Component, ReactNode } from "react";
import "./CommentPage.scss";
import axios from 'axios';
import { Message } from "@material-ui/icons";
import { Box } from "@material-ui/core";

interface Comment {
    name: string;
    value: string;
}

export class CommentPage extends Component<any, { comments: Comment[] }> {
    constructor(props: any) {
        super(props);
        this.state = { comments: [{ name: "a", value: "b" }] };
        this.updateComments = this.updateComments.bind(this);
    }

    updateComments(newComments: Comment[]) {
        this.setState({ comments: newComments });
    }

    public render(): ReactNode {
        return (
            <div>
                <Form onUpdateComments={this.updateComments} />
                <Mlist comments={this.state.comments} />
            </div>
        )
    }
}

class Form extends Component<{ onUpdateComments: (comments: Comment[]) => void }, { name: string, message: string }> {
    constructor(props: { onUpdateComments: (comments: Comment[]) => void }) {
        super(props);
        this.state = { name: '', message: '' };

        this.handleChangeName = this.handleChangeName.bind(this);
        this.handleChangeMess = this.handleChangeMess.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChangeName(event: React.ChangeEvent<HTMLInputElement>) {
        this.setState({ name: event.target.value, message: this.state.message });
    }

    handleChangeMess(event: React.ChangeEvent<HTMLInputElement>) {
        this.setState({ name: this.state.name, message: event.target.value });
    }

    handleSubmit(event: React.FormEvent<HTMLFormElement>) {
        event.preventDefault();
        axios.post('http://localhost:8080/addComment', {
            author: this.state.name,
            comment: this.state.message
        }).then(() => {
            axios.get<Comment[]>('http://localhost:8080/allComments').then(r => {
                this.props.onUpdateComments(r.data);
                this.setState({ name: this.state.name, message: '' });
            })
        }).catch(err => {
            alert(err.message);
        })
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <label>
                    Name
                    <input type="text" value={this.state.name} onChange={this.handleChangeName} />
                    Message
                    <input type="text" value={this.state.message} onChange={this.handleChangeMess} />
                </label>
                <input type="submit" value="Submit" />
            </form>
        );
    }
}

class Mlist extends Component<{ comments: Comment[] }, {}> {
    render() {
        return (
            <ul>
                {this.props.comments.map((comment, index) => (
                    <li key={index}>{comment.name}: {comment.value}</li>
                ))}
            </ul>
        );
    }
}
关键修改点:
  • 把列表数据放到父组件CommentPage的state中,通过props传递给Mlist组件,状态变化时自动触发重渲染
  • 修正axios响应数据获取:用r.data拿到服务器返回的列表
  • 给Form组件传递onUpdateComments方法,提交成功后更新父组件状态
  • 修复HTML语义错误:把包裹li的p标签改成ul
  • 循环渲染时添加唯一key属性,符合React要求

内容的提问来源于stack exchange,提问作者student422

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 06:50:52