使用 ReactDOM.render() 而不是在其容器组件内重新呈现应用程序——反模式?
Re-rendering an app using ReactDOM.render() rather than within its container component -- anti-pattern?
我有一个单一对象状态驱动的应用程序,其状态 dispatch/subscribe 逻辑与 React 'flow' 保持分离(即没有像 React-Redux 绑定这样的助手)。
当状态改变时,我的应用重新呈现。
以下两种实现之间是否有任何区别,或者是否存在任何反模式问题? (对不起,我没有使用 JSX,让任何人不高兴)
var myElementClass = React.createClass(
render : function() {
//make use of this.props.state...
}
);
var myAppContainerComponent = React.createElement(
myElementClass,
{state : dataStore.getState()}
);
dataStore.onChange(function(){
ReactDOM.render(myAppContainerComponent, someDOMContainer);
});
对比...
var myElementClass = React.createClass(
componentDidMount : function() {
var self = this;
this.props.store.onChange(function(){
self.setState(self.props.store.getState());
});
},
render : function() {
//make use of this.state...
}
);
var myAppContainerComponent = React.createElement(
myElementClass,
{store : dataStore}
);
ReactDOM.render(myAppContainerComponent, someDOMContainer);
第一个强制应用程序范围从 'outside' 重新呈现,即使用 ReactDOM。第二个在容器应用程序中做同样的事情。
我已经进行了一些性能测试,实际上并没有发现任何区别。我会 运行 解决未来的问题吗?多次点击 ReactDOM.render() 是个问题吗?
我知道有些人会评论说这两种方式都可能很昂贵,因为它们各自重新渲染整个应用程序(这不是 React 的目的;)),但这超出了这个问题的范围。
我认为你的组件应该是一个纯函数,无论它碰巧在它之外的任何状态,但不知道那个状态(好吧,"pure" 它可以合理地是)。
我在第二个示例中看到 "leaky implementation",这意味着当您有:
componentDidMount : function() {
var self = this;
this.props.store.onChange(function(){
self.setState(self.props.store.getState());
});
},
您将组件本身与应该导致组件重新呈现的函数混为一谈。
你的第一个实现似乎更适合我。此外,第一个实现 lot 可重用性更高。
在你的第二个例子中,如果你想改变你的数据存储、渲染等的结构怎么办?那么您可能必须深入研究每个组件并进行更改。
最重要的是,我绝对更喜欢第一个实现。
当你有几个组件时没有太大区别,但当你的应用程序变大时,从顶部重新渲染会导致速度变慢。这就是为什么我建议将单个组件订阅到商店,并且仅在 他们关心的状态部分发生变化时才使用 setState()
。这样,您的组件将随着应用程序的增长而变得更加高效。
最后,不建议大家直接使用store.subscribe()
。有一个名为 React Redux 的完整图书馆可以为您进行订阅!当你从它使用 connect()
时,它会用 setState()
逻辑包装你的组件,所以你不必编写它,你只需要指定你的组件关心的状态部分。 此外,React Redux 比您手写的代码更高效,因为它包含许多优化。
我有一个单一对象状态驱动的应用程序,其状态 dispatch/subscribe 逻辑与 React 'flow' 保持分离(即没有像 React-Redux 绑定这样的助手)。
当状态改变时,我的应用重新呈现。
以下两种实现之间是否有任何区别,或者是否存在任何反模式问题? (对不起,我没有使用 JSX,让任何人不高兴)
var myElementClass = React.createClass(
render : function() {
//make use of this.props.state...
}
);
var myAppContainerComponent = React.createElement(
myElementClass,
{state : dataStore.getState()}
);
dataStore.onChange(function(){
ReactDOM.render(myAppContainerComponent, someDOMContainer);
});
对比...
var myElementClass = React.createClass(
componentDidMount : function() {
var self = this;
this.props.store.onChange(function(){
self.setState(self.props.store.getState());
});
},
render : function() {
//make use of this.state...
}
);
var myAppContainerComponent = React.createElement(
myElementClass,
{store : dataStore}
);
ReactDOM.render(myAppContainerComponent, someDOMContainer);
第一个强制应用程序范围从 'outside' 重新呈现,即使用 ReactDOM。第二个在容器应用程序中做同样的事情。
我已经进行了一些性能测试,实际上并没有发现任何区别。我会 运行 解决未来的问题吗?多次点击 ReactDOM.render() 是个问题吗?
我知道有些人会评论说这两种方式都可能很昂贵,因为它们各自重新渲染整个应用程序(这不是 React 的目的;)),但这超出了这个问题的范围。
我认为你的组件应该是一个纯函数,无论它碰巧在它之外的任何状态,但不知道那个状态(好吧,"pure" 它可以合理地是)。
我在第二个示例中看到 "leaky implementation",这意味着当您有:
componentDidMount : function() {
var self = this;
this.props.store.onChange(function(){
self.setState(self.props.store.getState());
});
},
您将组件本身与应该导致组件重新呈现的函数混为一谈。
你的第一个实现似乎更适合我。此外,第一个实现 lot 可重用性更高。
在你的第二个例子中,如果你想改变你的数据存储、渲染等的结构怎么办?那么您可能必须深入研究每个组件并进行更改。
最重要的是,我绝对更喜欢第一个实现。
当你有几个组件时没有太大区别,但当你的应用程序变大时,从顶部重新渲染会导致速度变慢。这就是为什么我建议将单个组件订阅到商店,并且仅在 他们关心的状态部分发生变化时才使用 setState()
。这样,您的组件将随着应用程序的增长而变得更加高效。
最后,不建议大家直接使用store.subscribe()
。有一个名为 React Redux 的完整图书馆可以为您进行订阅!当你从它使用 connect()
时,它会用 setState()
逻辑包装你的组件,所以你不必编写它,你只需要指定你的组件关心的状态部分。 此外,React Redux 比您手写的代码更高效,因为它包含许多优化。