javascript - ReactJs + Reflux//触发在null组件上执行?

标签 javascript reactjs refluxjs

我正在尝试在我的 ReactJs 应用程序中使用 Reflux。

我遇到一个问题,即监听数据存储的组件正在空组件实例而不是实例化的实际组件上执行回调。

调用操作toggleUserBar后,将调用数据存储并执行触发器。在组件Sidebar中,调用了回调但组件状态为空:

Uncaught TypeError: Cannot read property 'sd' of undefined

知道我做错了什么吗?

actions.tsx

var Reflux = require('reflux');
var RQ = {};

RQ.actions = Reflux.createActions([
    "toggleUserBar"
]);

window.RQ = RQ;

store.tsx

RQ.store = Reflux.createStore({
  listenables: [RQ.actions],
  init: function() {},
  onToggleUserBar: function() {
      this.trigger();
  }
});

sidebar.tsx

import * as React from "react";
import * as ReactDOM  from "react-dom";

const LeftNav = require('material-ui/lib/left-nav');
const Menu = require('material-ui/lib/menu/menu')

interface ISidebarProps extends React.Props<any> {

}

interface ISidebarState extends React.Props<any> {
    shown: Boolean;
    sd: any;
}

export class Sidebar extends React.Component<ISidebarProps, ISidebarState> {

  unsubscribe: any;

  constructor(props: ISidebarProps) {
      super(props);
      this.state = { shown: true, sd: null };
  };

  componentDidMount() {
    this.unsubscribe = RQ.store.listen(function() {
      this.state.sd.setState({ open: true });
    });
  };

  componentWillUnmount() {
      this.unsubscribe();
  };

  render() {

    let menuItems = [
      { route: 'get-started', text: 'Get Started' },
      { route: 'customization', text: 'Customization' },
      { route: 'components', text: 'Components' }
    ];

    return (
      <LeftNav ref={(c) => this.state.sd = c} docked={false} openRight={true} menuItems={menuItems} />
    );

  };

}

侧边栏组件在另一个组件中渲染:

<ComSidebar ref={(c) => sdref = c} />

如果我手动调用sdref.state.sd.open = true,它就可以正常工作。

最佳答案

JavaScript 中的 this 关键字通常会以令人惊讶的方式表现。您已经找到了主要的一个。

当您使用 function 关键字创建内部函数时,它不会获得与封闭函数相同的 this 变量。这意味着,在您的代码中:

componentDidMount() {
  // "this" out here is your component instance
  this.unsubscribe = RQ.store.listen(function() {
    // "this" in here is NOT the same - undefined, as you're seeing
    this.setState({ open: true });
  });
};

有多种方法可以解决此问题。由于您使用的是 ES6,最简单的可能是使用箭头函数 - 箭头函数显式保留其封闭函数的 this 引用。它看起来像这样:

componentDidMount() {
  this.unsubscribe = RQ.store.listen(() => {
    // now it's the same "this"
    this.setState({ open: true });
  });
};

如果您没有使用 ES6,您可以通过在该函数上调用 bind 来获得相同的行为(这允许您指定 this 变量,以及任何参数):

componentDidMount() {
  this.unsubscribe = RQ.store.listen(function() {
    this.setState({ open: true });
  }.bind(this)); 
  // by calling bind, we are explicitly setting the "this" variable here
  // passing it from outer scope to inner scope
};

关于javascript - ReactJs + Reflux//触发在null组件上执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34372902/

相关文章:

javascript - 使用reactjs,更新列表中的项目而不更新整个列表?

javascript - react : Rendering a list in reverse order

javascript - Flux:Stores 是否应该通知组件发生了什么变化?

javascript - <BrowserRouter> 忽略 history Prop

javascript - 在 jsx 中进行计算

javascript - React 高阶元素 - 传递 Prop 可以走多远

javascript - 如何在 HTML5 Canvas 上移动绘制的图像?

javascript - Highchart 线不显示

javascript - 返回 JS 中的今天日期

javascript - 如何显示来自 json 文件的标记列表?