这在 React class 函数中为 null

this is null in React class function

我将我的 React class 从 ES5 重构为 ES6,现在当我单击一个调用 this.state.dispatch(logIn(this.state.logIn)) 的按钮时,该行开头的初始 this 是无效的。超级奇怪。

这是我的 class:

class Home extends Component {
    constructor(props) {
        super(props);

        this.state = {
            panelIsOpen: false,
            registration: {},
            login: {},
        };
    }

    signUp() {
        this.props.dispatch(signUp(this.state.registration));

        this.setState({
            registration: {},
        });
    }

    logIn() {
        debugger; // this is `null here`
        this.props.dispatch(logIn(this.state.login));

        this.setState({
            login: {},
        });
    }

    togglePanel(e) {
        this.setState({ panelIsOpen: !this.state.panelIsOpen} );
    }

    render() {
        const {elements} = this.props;
        const {registration, login} = this.state;

        return (
            // some stuff 
        );
    }
};

Home.propTypes = {
    elements: React.PropTypes.array,
    dispatch: React.PropTypes.func,
    user: React.PropTypes.object,
};

const mapStateToProps = ({elements, auth}) => {
    return {
        elements: getElementsByKeyName(elements, 'visibleElements'),
        user: getLoggedInUser(auth),
    };
};

Home = DragDropContext(HTML5Backend)(Home);
export default connect(mapStateToProps)(Home);

点击登录按钮调用登录函数,但由于某些原因,thisnull

感谢观看

React 不会绑定添加到 ES6 类 的方法的上下文,除非它们是标准 React 生命周期的一部分(componentWillReceivePropscomponentDidMount,等等).

这意味着您需要为 signUplogIntogglePanel 方法手动绑定 this 的值,或者将它们声明为箭头函数,继承父上下文。

1.

constructor(props) {
  super(props);
  this.signUp = this.signUp.bind(this);
  this.logIn = this.logIn.bind(this);
  this.togglePanel = this.togglePanel.bind(this);

  this.state = {
    panelIsOpen: false,
    registration: {},
    login: {},
  }

2.

signUp = () => {
  this.props.dispatch(signUp(this.state.registration));

  this.setState({
    registration: {},
  });
}

// the same for logIn and togglePanel

参考 the docs

这(没有双关语意)与函数在 ES6 中的绑定方式有关。如果您将您的方法作为 prop 传递给另一个组件,则不能保证它所在的上下文 运行 是正确的上下文(除非您先绑定它)。这是一篇很长但有趣的文章:http://reactkungfu.com/2015/07/why-and-how-to-bind-methods-in-your-react-component-classes/

简而言之,您有几个选择:

  1. (pretty common/popular) 在构造函数中将您的方法绑定到 this。您可能不需要绑定所有方法 - 取决于它们的使用方式。

    constructor(props) {
        super(props);
        this.state = {
            panelIsOpen: false,
            registration: {},
            login: {},
        };
        this.signUp = this.signUp.bind(this);
        this.signUp = this.logIn.bind(this);
        this.togglePannel = this.togglePannel.bind(this);
    } 
    
  2. 将您的方法定义为箭头函数,这将为您将其绑定到当前范围 - 无需在构造函数中绑定它们:

    class Home extends Component {
        // ...
    
        signUp = () => {
            this.props.dispatch(signUp(this.state.registration));
    
            this.setState({
                registration: {},
            });
        }
    
        // ...
    }