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