当我在var xsltCompiled = new System.Xml.Xsl.XslCompiledTransform(enableDebug:true);
xsltCompiled.Load(stylesheetUri:xsltFile);
xsltCompiled.Transform(inputUri:xmlInputFile,resultsFile:anyOutputFile);
中拨打ReactDom.render
时,只会创建一个init()
标记,并且会在此g
标记内创建所有圈子。但是我希望每次调用g
时都必须创建一个单独的ReactDom.render
标记。我对React中组件的了解是我们可以使用g
实例化我们想要的任意组件。我怎样才能做到这一点?
React.createClass
答案 0 :(得分:2)
您可能会发现,您可以通过让React组件定义代码结构而不是自己的函数和全局变量来获益。
一般来说,如果你发现自己多次调用ReactDOM.render
,那么可能会出现问题。
不是将100个组件渲染到一个元素中,而是定义一个由100个子组件实例组成的顶级组件,然后再渲染一次。
var Graphics = React.createClass({
// ...
});
ReactDOM.render(
React.createElement(Graphics, null),
document.getElementById('svg')
);
我们将创建一个Graphics
组件,我们可以将其用作其余组件的父组件。 我们只需要渲染一次。
不要将圆圈列表存储在全局数组中,而是使用新顶级组件上的state属性。这样,无论何时更新它,组件都将重新渲染以反映更改。
getInitialState: function() {
// by default there are no circles (empty array)
return { circles: [] };
},
componentWillMount: function() {
var circles = [];
for(var i = 0; i < 100; i++) {
// rather than storing actual circles, we just store
// the props that are needed to create them
circles.push({
cx: randomNumber(1200, 40),
cy: randomNumber(600, 40),
r: randomNumber(30,20)
});
}
this.setState({ circles: circles });
}
getInitialState
允许我们为this.state
上的属性定义默认值,而componentWillMount
允许在组件在DOM中呈现之前运行代码。
现在Graphics组件知道圆圈列表,我们必须描述它应该呈现的方式。
render: function() {
var circles = this.state.circles.map(function(props) {
return React.createElement(Circle, props);
});
return React.createElement('g', null, circles);
}
此功能使用map
使用我们存储在Circle
中的道具创建this.state.circles
组件。
当您将组件构建在一个顶级容器组件中时,React是最有效的,就像我们在这里创建的那样。你不应该做任何必要的操作(比如每次循环和渲染组件),而应该寻找声明性的替代方案。
React希望你告诉它你想要什么,而不是应该如何。
在这种情况下,你想要的是一个组件,里面有许多随机大小和定位的圆圈,但你试图做的是向React 解释它应该是为了实现这一目标。
var Circle = React.createClass({
render: function() {
// ...
}
});
var Graphics = React.createClass({
getInitialState: function() {
// ...
},
componentWillMount: function() {
// ...
},
render: function() {
// ...
}
});
生成的代码不仅应该更短,更容易理解,而且还易于重构。如果没有太多工作,您可以将配置详细信息(例如圈数)移到Graphics
的支柱上。