首页 > 解决方案 > React 组件渲染但未安装,因此无法设置状态

问题描述

我有一个名为 FillForm 的功能组件,它调用要在 FormFiller 函数中按顺序呈现的对象列表。这些组件正在正确渲染和显示,但是当试图让它们改变它们的内部状态时,我得到了错误

警告:无法在尚未安装的组件上调用 setState。这是一个无操作,但它可能表明您的应用程序中存在错误。相反,在 MultipleChoiceQuestion 组件中直接分配this.state或定义state = {};具有所需状态的类属性。

这是formfiller函数:

const FillForm = props => {

return (
    <div className={classes.container} key={1}>
        <p>Form Filler</p>
        {formElements[currentPage].map((Element => (
            Element.render()
        )))}
        <Button variant="contained" disabled={backDisabled} onClick={handleBack}>BACK</Button>
        <SubmitButton />
    </div>
)

}

我已经删除了与这里的问题无关的代码,但是 formElements 都是我的 BaseElement 的子元素,而 formElements 对象是上述需要按顺序呈现的类对象的列表。

import React from "react"
  class BaseEntry extends React.Component {
constructor(props) {
    super(props);
    this.key = 0
    this.type = ""
}
setID(id) {
    this.key = id;
}
setType(type) {
    this.type = type;
}

userResponse() {
    return (null);
}
//This should always be overridden
render() {
    return (
        <React.Fragment>
            <div></div>
        </React.Fragment>
    )
}} export default BaseEntry;

以下是当我尝试在多项选择题中选择不同选项时给我带来问题并给出错误的代码。

class MultipleChoiceQuestion extends BaseEntry {
    constructor(question_text, choices) {
        super();
        this.question_text = question_text //A string
        this.choices = choices // [[1, "Choice text"], [2, "Choice text two"]]
        this.response = 1
        this.handleChange = this.handleChange.bind(this) 
        this.state = {response: 1}     
    }

    userResponse() {
        return ({
            "id" : this.id,
            "response" : this.response,
            "type" : this.type
        })
    }

    componentDidMount() {
        console.log("mounted")
    }

    handleChange(e) {
        console.log(e.target.value)
        this.setState({response: e.target.value})
    }
    
    render() {
        return (
            <React.Fragment key={this.key}>
                <div>
                    <h2>{this.response}</h2>
                    <FormControl component="fieldset">
                        <RadioGroup aria-label={this.question_text} value={this.response} name={this.question_text} onChange={this.handleChange}>
                            {this.choices.map(((choice, index) => (
                                <FormControlLabel value={choice[0]} control={<Radio />} label={choice[1]} key={index}/>
                            )))}
                        </RadioGroup>
                    </FormControl>
                </div>
            </React.Fragment>
        );
    }
}

export default MultipleChoiceQuestion; 

这是代码框:[https://codesandbox.io/s/priceless-leavitt-yh5dp?file=/src/FillForm.js]

标签: javascriptreactjsmaterial-uistate

解决方案


render() {
    return (
        <React.Fragment key={this.key}> {/* remove key form here as your component dosen't have it */}
            <div>
                <h2>{this.state.response}</h2> {/* here is the problem use `this.state.resopnse` instead of `this.response` */}
                <FormControl component="fieldset">
                    <RadioGroup aria-label={this.question_text} value={this.response} name={this.question_text} onChange={this.handleChange}>
                        {this.choices.map(((choice, index) => (
                            <FormControlLabel value={choice[0]} control={<Radio />} label={choice[1]} key={index}/>
                        )))}
                    </RadioGroup>
                </FormControl>
            </div>
        </React.Fragment>
    );
}

this.response在渲染函数中使用你应该使用this.state.response. 并从this.key片段中删除,因为您的组件没有这样的 .


推荐阅读