setState(...):这通常意味着您在未安装的组件上调用了set state()

时间:2017-08-10 12:47:59

标签: javascript reactjs state

React,setState(...):,在setState()组件上调用unmounted ???

setState(...):这通常意味着您在已卸载的组件上调用了set state()。

  

警告:   setState(...):只能更新已安装或安装的组件。   这通常意味着您在已卸载的组件上调用set state()。   这是一个无操作。请检查TestModal组件的代码。

我只是想不通,这有什么问题?

```JSX

class TestModal extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = {
            loading: false,
            visible: true
        };
    }
    onTest = () => {
        // copy state, do test fetch
        this.testOK();
    };
    handleSubmit = (e) => {
        e.preventDefault();
        this.props.form.validateFields(
            (err, values) => {
                if (!err) {
                    console.log('Received values of form: ', values);
                    console.log('fetch url = \n', values.textarea);
                    // fetch data
                    let url = values.textarea;
                    this.props.checkTestCommands(url);
                    this.onTest();
                }else{
                    throw new Error(Error.name, Error.message);
                }
            }
        );
    };
    testOK = () => {
        this.setState({
            loading: true
        });
        this.props.hideModal();
        setTimeout(() => {
            this.setState({
                loading: false,
                visible: false
            });
        }, 1000);
    }
    testCancel = () => {
        this.setState({
            visible: false
        });
        this.props.hideModal();
    }
    render() {
        const {getFieldsValue, getFieldValue, setFieldsValue, getFieldDecorator} = this.props.form;
        const formItemLayout = {
            labelCol: {
                span: 6
            },
            wrapperCol: {
                span: 14
            }
        };
        return (
            <div>
                {/* query object */}
                {/* no footer */}
                <Modal 
                    title="命令行"
                    onOk={this.testOK}
                    onCancel={this.testCancel}
                    visible={this.state.visible}
                    footer={[]}
                    >
                    {/* loading={this.state.loading} */}
                    <Form 
                        onSubmit={this.handleSubmit}
                        layout="horizontal">
                        <FormItem
                            label="测试命令行"
                            hasFeedback
                            {...formItemLayout}>
                            {
                                getFieldDecorator('textarea', {
                                    rules: [
                                        {
                                            required: false,
                                            message: ' url 长度必须 30 个字符之间'
                                        }
                                    ],
                                    initialValue: `http://10.1.5.31:8080/http/report/query?{"ApiName":"JY.Topic.Market_profile.Investors_data_statistics.AccountStatistics"}`,
                                })(
                                    <Input
                                        type="textarea"
                                        placeholder="请先点击 “开始测试” 按钮!"
                                        rows="10"
                                        cols="70"
                                        />
                                )
                            }
                        </FormItem>
                        {/* onClick={this.props.checkTestCommands} */}
                        <FormItem style={{textAlign: "center"}}>
                            <Button 
                                onClick={this.onTest}
                                type="primary"
                                htmlType="submit"
                                icon="hourglass"
                                style={{margin: "auto 10px"}}
                                loading={this.state.loading}>
                                开始测试
                            </Button>
                            <Button 
                                onClick={this.testCancel}
                                size="large"
                                style={{margin: "auto 10px"}}
                                icon="close">
                                关闭
                            </Button>
                            {/* ref="submit_btn" */}
                        </FormItem>
                    </Form>
                </Modal>
            </div>
        );
    }
}

```

这是一个新版本的代码,但它仍然不起作用?

class TestModal extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = {
            loading: false,
            visible: true
        };
    }
    onTest = () => {
        // copy state, do test fetch
        this.testOK();
    };
/*     componentWillUnmount(){
        this.props.hideModal();
        this.setState({
            loading: false,
            visible: false
        });
    } */
    handleSubmit = (e) => {
        e.preventDefault();
        this.props.form.validateFields(
            (err, values) => {
                if (!err) {
                    console.log('Received values of form: ', values);
                    console.log('fetch url = \n', values.textarea);
                    // fetch data
                    let url = values.textarea;
                    this.props.checkTestCommands(url);
                    this.onTest();
                }else{
                    throw new Error(Error.name, Error.message);
                }
            }
        );
    };
    testOK = () => {
        this.setState({
            loading: true
        });
        setTimeout(() => {
            this.setState({
                loading: false,
                visible: false
            });
            this.props.hideModal();
        }, 1000);
    }
    testCancel = () => {
        this.setState({
            visible: false
        });
        this.props.hideModal();
    }
    render() {
        const {getFieldsValue, getFieldValue, setFieldsValue, getFieldDecorator} = this.props.form;
        const formItemLayout = {
            labelCol: {
                span: 6
            },
            wrapperCol: {
                span: 14
            }
        };
        return (
            <div>
                {/* query object */}
                {/* no footer */}
                <Modal 
                    title="命令行"
                    onOk={this.testOK}
                    onCancel={this.testCancel}
                    visible={this.state.visible}
                    footer={[]}
                    >
                    {/* loading={this.state.loading} */}
                    <Form 
                        onSubmit={this.handleSubmit}
                        layout="horizontal">
                        <FormItem
                            label="测试命令行"
                            hasFeedback
                            {...formItemLayout}>
                            {
                                getFieldDecorator('textarea', {
                                    rules: [
                                        {
                                            required: false,
                                            message: ' url 长度必须 30 个字符之间'
                                        }
                                    ],
                                    initialValue: `http://10.1.5.31:8080/http/report/query?{"ApiName":"JY.Topic.Market_profile.Investors_data_statistics.AccountStatistics"}`,
                                })(
                                    <Input
                                        type="textarea"
                                        placeholder="请先点击 “开始测试” 按钮!"
                                        rows="15"
                                        cols="500"
                                        />
                                )
                            }
                        </FormItem>
                        {/* onClick={this.props.checkTestCommands} */}
                        <FormItem style={{textAlign: "center"}}>
                            <Button 
                                onClick={this.onTest}
                                type="primary"
                                htmlType="submit"
                                icon="hourglass"
                                style={{margin: "auto 10px"}}
                                loading={this.state.loading}>
                                开始测试
                            </Button>
                            <Button 
                                onClick={this.testCancel}
                                size="large"
                                style={{margin: "auto 10px"}}
                                icon="close">
                                关闭
                            </Button>
                            {/* ref="submit_btn" */}
                        </FormItem>
                    </Form>
                </Modal>
            </div>
        );
    }
}

一个screencut gif!

enter image description here

2 个答案:

答案 0 :(得分:3)

在你的testOK方法中,当TestModal表单已经关闭(即组件已经卸载)延迟1秒后,您正在调用setState。这是一个noop。

答案 1 :(得分:0)

这是我的解决方案之一!

  

万岁,它现在有效!只需删除重复的集visible=false,它应始终为visible=true;   因为应该调用父组件的方法来实现show/hide本身!

感谢所有人,他回答了这个问题!

```JSX

class TestModal extends Component {
constructor(props, context) {
    super(props, context);
    this.state = {
        loading: false,
        visible: true
    };
}
onTest = () => {
    // copy state, do test fetch
    this.testOK(); 
};
handleSubmit = (e) => {
    e.preventDefault();
    this.props.form.validateFields(
        (err, values) => {
            if (!err) {
                console.log('Received values of form: ', values);
                console.log('fetch url = \n', values.textarea);
                // fetch data
                let url = values.textarea;
                this.props.checkTestCommands(url);
                // this.onTest();
            }else{
                throw new Error(Error.name, Error.message);
            }
        }
    );
};
testOK = (e) => {
    // e.preventDefault();
    console.log(`testOK e`, e);
    this.setState({
        loading: true
    });
    setTimeout(() => {
        this.setState({
            loading: false
        });
        this.props.hideModal();
    }, 1000);
}
testCancel = () => {
   this.props.hideModal();
}
render() {
    const {getFieldsValue, getFieldValue, setFieldsValue, getFieldDecorator} = this.props.form;
    const formItemLayout = {
        labelCol: {
            span: 6
        },
        wrapperCol: {
            span: 14
        }
    };
    // destructuring assignment
    const {visible, loading} = this.state;
    return (
        <div>
            {/* query object */}
            {/* no footer */}
            <Modal 
                title="命令行"
                onOk={this.testOK}
                onCancel={this.testCancel}
                visible={visible}
                footer={[]}
                >
                {/* loading={this.state.loading} */}
                <Form 
                    onSubmit={this.handleSubmit}
                    layout="horizontal">
                    <FormItem
                        label="测试命令行"
                        hasFeedback
                        {...formItemLayout}>
                        {
                            getFieldDecorator('textarea', {
                                rules: [
                                    {
                                        required: false,
                                        message: ' url 长度必须 30 个字符之间'
                                    }
                                ],
                                initialValue: `10.1.5.31:8080/http/report/query?{"SecuCode":"000011","Names":"阳琨","ApiName":"fund.f9.fund_profile.FundManager.BasicInformations","WriteType":"json"}`,
                            })(
                                <Input
                                    type="textarea"
                                    placeholder="请先点击 “开始测试” 按钮!"
                                    rows="15"
                                    cols="500"
                                    />
                            )
                        }
                    </FormItem>
                    {/* onClick={this.props.checkTestCommands} */}
                    <FormItem style={{textAlign: "center"}}>
                        <Button 
                            onClick={this.onTest}
                            type="primary"
                            htmlType="submit"
                            icon="hourglass"
                            style={{margin: "auto 10px"}}
                            loading={loading}>
                            开始测试
                        </Button>
                        <Button 
                            onClick={this.testCancel}
                            size="large"
                            style={{margin: "auto 10px"}}
                            icon="close">
                            关闭
                        </Button>
                        {/* ref="submit_btn" */}
                    </FormItem>
                </Form>
            </Modal>
        </div>
    );
}

}

```