React.js:对外部对象的变化做出反应

mtk*_*nko 4 javascript reactjs

阅读官方react.js文档后,我了解它应该如何以良好的方式工作,例如

  1. 我有处于初始组件状态的项目列表
  2. 通过setState添加新项目将更新状态并触发 UI 更新

如果我使用外部对象作为模型,比如一些全局数组,它应该可用于某些非react.js代码部分,或者将来可以在某个地方使用 Web 套接字进行修改,我该怎么办?在每个动作之后调用ReactDOM.render是一种好方法吗?AFAIK 从性能的角度来看,它应该可以正常工作。

Mik*_*ans 6

你仍然使用setState

let React = require('React');
let externalThing = require('tools/vendor/whoever/external-lib');

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = this.getInitialState();
  }
  getInitialState() {
    // This assumes your external thing is written by someone who was
    // smart enough to not allow direct manipulation (because JS has
    // no way to monitor primitives for changes), and made sure
    // to offer API functions that allow for event handling etc.
    externalThing.registerChangeListener(() => this.updateBasedOnChanges(externalThing));
    return { data: externalThing.data }        
  }
  updateBasedOnChanges(externalThing) {
    // note that setState does NOT automatically trigger render(),
    // because React is smarter than that. It will only trigger
    // render() if it sees that this new 'data' is different
    // (either by being a different thing entirely, or having
    // different content)
    this.setState({
      data: externalThing.data
    });
  }
  render() {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

如果你使用的外部东西写得很糟糕,你必须直接操作它的数据,你的第一步是为它编写一个 API,这样你就不会直接操作这些数据。

let externalData = require('externaldata') // example: this is a shared array
let ExternalDataAPI = new ExternalDataAPI(externalData);
...
Run Code Online (Sandbox Code Playgroud)

然后确保 API 具有所有更新和事件挂钩:

class ExternalDataAPI {
  constructor(data) {
    this.data = data;
    this.listeners = [];
  }
  addListener(fn) {
    this.listeners.push(fn);
  }
  update(...) {
    // do something with data
    this.listeners.forEach(fn => fn());
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

或者,有些框架已经为您执行了此操作(flux 等),但它们也在某种程度上规定了“应该完成”多少事情,因此这可能对您的需求来说太过分了。