有关定义道具和状态的问题

时间:2020-03-09 12:27:57

标签: reactjs typescript types next.js

我遇到以下错误:

'{[x:number]类型的参数:任意; }'不可分配给 'PostState |类型的参数((prevState:只读, 道具:Readonly <{}>)=> PostState |选择| null)| 选择<...> |空值'。类型“ {{[x: 数字:任何; }”,但在“选择”类型中为必填项。

在此行:

handleChange = ({target} : any) => {
        const {name, value} = target;
        this.setState({[name]: value}); // I GET THE ERROR HERE
    };

这是我的代码:

interface Post{
name: string;
body: string;
title: string;
_id: number | string;
date: Date;
}

interface PostState{
posts: Post[];
}
class ABC extends React.Component <{},PostState> {
    state = {
        title: '',
        name: '',
        date: '',
        body: '',
        posts: []
    };

    handleChange = ({target} : any) => {
        const {name, value} = target;
        this.setState({[name]: value});
    };
    submit = (event : any) => {
        event.preventDefault();
        const payload = {
            title: this.state.title,
            body: this.state.body,
            name: this.state.name
        };

        axios({url: 'http://localhost:8080/api/save/', method: 'POST', data: payload}).then(() => {
            console.log("Data has been sent to the server");
            this.resetUserInputs();
        }).catch(() => {
            console.log("Internal server error");
        })
    };

    resetUserInputs = () => {
        this.setState({title: '', body: '', name: ''})
    };

    render() {
        console.log('state', this.state);
        return (
            <div>
                <Nav/>
                <Box>
                    <Title>
                        <TextName>New Question</TextName>
                    </Title>
                    <form onSubmit={this.submit}>

                        <div className="form-input">
                            <H5 >Name
                                <InputName
                                    type="text"
                                    name="name"
                                    placeholder="Enter your full name here"
                                    value={this.state.name}
                                    onChange={this.handleChange}/>
                            </H5>
                        </div>

                        <div className="form-input">
                            <H5 >Title
                                <InputTitle
                                    type="text"
                                    name="title"
                                    placeholder="What's your question? Be specific"
                                    value={this.state.title}
                                    onChange={this.handleChange}/>
                            </H5>
                        </div>

                        <div className="form-input">
                            <QuestionText >Question</QuestionText>
                            <Questionbox
                                placeholder="Start your question with What OR How OR Why"
                                name="body"
                                rows={4}
                                cols={30}
                                value={this.state.body}
                                onChange={this.handleChange}/>
                        </div>

                        <Footer>
                            <div className="post-form-buttons">

                                <Button>Add Question</Button>
                                <Cancel>
                                    <Link href={`/`}>
                                        <A>
                                            Cancel
                                        </A>
                                    </Link>
                                </Cancel>
                            </div>
                        </Footer>

                    </form>
                </Box>
            </div>
        );
    }
}

export default ABC

1 个答案:

答案 0 :(得分:0)

您看到的问题错误是由于在this.setState中使用了索引,而在PostState界面中未定义索引签名。

像这样添加索引签名将消除此错误。

  interface PostState{
    posts: Post[];
    [key: string]: any;
  }

此外,您可以将目标定义为事件,并告诉打字稿目标是具有namevalue属性的输入,以提高类型安全性

  handleChange = ({target}: Event) => {
      const {name, value} = target as HTMLInputElement;
      this.setState({[name]: value});
  };

我注意到的另一件事是,您似乎将状态键设置为单个帖子的键,但是将状态定义为具有帖子数组。

详细说明高级修复程序

是的,尽管您将需要使用TypeType的多个类型和一些更高级的功能,但是您可以通过更安全的类型来解决此问题。

类似下面的代码会让您接近,但是仍然存在一个小问题,即您的状态是使用date属性定义为字符串,并且在您的Post界面中,它被定义为{的实例{1}}。您必须通过定义一个联合或创建另一个将date属性定义为字符串的单独接口来决定如何解决此问题。

Date