Javascript React.js:对外部对象中的更改作出反应

Javascript React.js:对外部对象中的更改作出反应,javascript,reactjs,Javascript,Reactjs,在阅读了官方react.js文档之后,我理解了它应该如何以良好的方式工作,比如 我有处于初始组件状态的项目列表 通过设置状态添加新项将更新状态并触发UI更新 如果我使用外部对象作为模型,比如某个全局数组,该数组应可用于某些非react.js代码部分,或者将来某个地方可以使用web套接字进行修改,我该怎么办?在每个操作后调用ReactDOM.render是否是一种好方法?从性能的角度来看,它应该可以正常工作。因为您的问题是如何以可管理的方式组织代码,我首先建议将ReactJS与Flux类型的框架(

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

  • 我有处于初始组件状态的项目列表
  • 通过设置状态添加新项将更新状态并触发UI更新

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

    因为您的问题是如何以可管理的方式组织代码,我首先建议将ReactJS与Flux类型的框架(如Redux或Relay)配对

    如果您现在想跳过这一步,那么您可以使用层次结构顶部的一些react组件来组织项目,以存储和检索数据。例如,在这样的组件中,可以在其方法中启动
    setTimeout
    ,定期检查全局数组,并在适当时调用
    setState
    。然后,render方法应该包含作为道具接收此状态的子组件

    下面是一个例子。显然,计时器可以被用于订阅数据更改的任何方法所取代

    //您的全局对象
    var globalState={name:“福尔摩斯”}
    函数onData(回调){
    setInterval(函数(){
    回调(全局状态)
    }, 1500)
    }
    var Child=React.createClass({
    render:function(){
    返回Hello,{this.props.name};
    }
    });
    var Root=React.createClass({
    getInitialState:函数(){
    返回{}
    },
    componentWillMount:function(){
    var=这个;
    this.props.onData(函数(数据){
    that.setState({external:data})
    })
    },
    render:function(){
    if(this.state.external)
    返回
    其他的
    返回装载。。。;
    }
    });
    反应域
    .render(,document.getElementById('container'))

    您仍然使用
    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() {
        // ...
      }
    }
    
    如果您正在使用的外部对象编写得非常糟糕,并且您必须直接操作它的数据,那么您的第一步就是为它编写一个API,这样您就不会直接操作该数据

    let externalData = require('externaldata') // example: this is a shared array
    let ExternalDataAPI = new ExternalDataAPI(externalData);
    ...
    
    然后确保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());
      }
      ...
    }
    

    或者,有些框架已经为您完成了这项工作(flux等),但它们也在一定程度上规定了“应该完成”的数量,因此可能会超出您的需要。

    组件的渲染方法在每次
    状态更改时都会被调用如果我自己更改状态(state-我指的是任何对象,而不是react.js state)并为组件触发ReactDOM.render-没有区别,对吧?我不能确切地说每次数据更改时调用ReactDOM.render会带来多少性能开销,但这似乎有些过分,react文档不推荐这样做。值得注意的是,这已经在babel中运行了,所以使用ES6很有意义:不
    that=this;function(){that.setState…
    ,只需使用上下文保持箭头函数:
    this.props.onData(data=>this.setState({external:data}))
    这是个不错的答案,但我认为关于“数据操纵”的判断部分首先,在这个用例中,
    externalThing
    可以是任何东西,可能只是由代码的某些其他方面或其他库维护的对象,谁说过API?其次,这不是关于从react内部进行数据操作?可能只是我们想插入到我们的pp-我们只需要它的数据,而我们无法真正改变它的方式或数据的更改/维护方式。因此,如果在react中没有简单的方法来做到这一点,为什么不承认它呢?或者,编写一个通用示例,明确说明假设,使用大量的代码注释来说明这一点,这可能是一个很好的主意展示它有多简单。API只是一个应用程序编程接口t:不管它是一个对象、一个库、一个网络服务,还是人们提出的任何其他东西,都可以访问他们需要的数据,并得到数据更改的通知。