Redux组件setState卸载警告

时间:2017-10-06 14:21:23

标签: typescript redux webpack-hmr

我在连接组件上遇到setState问题 - 它向我显示有关未安装的coumponent的警告。我设法修复它的唯一方法是编写如下代码:

import deepEqual = require('deep-equal');
import * as React from 'react';
import { connect } from 'react-redux';
import { Prompt } from 'react-router-dom';

// https://github.com/acdlite/flux-standard-action
export type Action<T>{
  type: string
  payload: T
  error?: boolean
  meta?: any
}

const actions: { [name: string]: (payload: any)  => Action<any>} = {
    saveValue: (settings: SettingsState) => ({ type: 'SAVE_SETTINGS', payload: settings }),
};

type StateToProps = {
    value: string;
};
type DispatchToProps = {
    saveValue: (state: SettingsState) => void;
};
type ConnectedProps = {
    header: string;
};

type SettingsProps = StateToProps & DispatchToProps & ConnectedProps;

type SettingsState = {
    value: string;
};

// funky class declaration
let Settings = class extends React.Component<SettingsProps, SettingsState> {
    static mapStateToProps(state: any): StateToProps {
        return {
            ...state.Example,
        };
    }

    static mapDispatchToProps(dispatch: (action: Action<any>) => void): DispatchToProps {
        return {
            saveValue: (settings: SettingsState) => {
                dispatch(actions.saveValue(settings));
            },
        };
    }

    constructor(props: SettingsProps) {
        super(props);
        this.state = {
            value: props.value,
        };
    }

    save = () => this.props.saveValue(this.state);

    onChange = (e: React.ChangeEvent<HTMLInputElement>) => { this.setState({ value: e.target.value }); };

    render() {
        return (
            <div>
                <input type="text" defaultValue={this.props.value} onChange={this.onChange} />
                <button onClick={this.save}>Save</button>
            </div>
        );
    }
};

// even funkier class variable reassign
Settings = connect<StateToProps, DispatchToProps, SettingsProps>
    (Settings.mapStateToProps, Settings.mapDispatchToProps)(Settings) as any;

export default Settings as React.ComponentClass<ConnectedProps>;

它有效,但如果我在代码中更改这些行:

-let Settings = class extends React.Component<SettingsProps, SettingsState> {
+class Settings extends React.Component<SettingsProps, SettingsState> {

以及其中一个:

-Settings = connect<StateToProps, DispatchToProps, SettingsProps>
-    (Settings.mapStateToProps, Settings.mapDispatchToProps)(Settings) as any;
+const AnotherVariable = connect<StateToProps, DispatchToProps, SettingsProps>
+    (Settings.mapStateToProps, Settings.mapDispatchToProps)(Settings) as any;

-export default Settings as React.ComponentClass<ConnectedProps>;
+export default AnotherVariable as React.ComponentClass<ConnectedProps>;

-OR -

-Settings = connect<StateToProps, DispatchToProps, SettingsProps>
-    (Settings.mapStateToProps, Settings.mapDispatchToProps)(Settings) as any;
-export default Settings as React.ComponentClass<ConnectedProps>;
+export default connect<StateToProps, DispatchToProps, SettingsProps>
+    (Settings.mapStateToProps, Settings.mapDispatchToProps)(Settings) 
+        as React.ComponentClass<ConnectedProps>;

我收到此警告:

Warning: setState(...): Can only update a mounted or mounting component. 
This usually means you called setState() on an unmounted component. 
This is a no-op.

Please check the code for the Settings component.

女巫很奇怪,因为从onChange事件处理程序调用了setState,并且组件在DOM中...

有什么想法吗?

编辑:经过一些测试后,我发现这段代码可以正常工作:

const Another = connect<StateToProps, DispatchToProps, SettingsProps>
    (Settings.mapStateToProps, Settings.mapDispatchToProps)(Settings) as any;
export default Another;

Settings = Another; // setState warning if this line is commented out

0 个答案:

没有答案