When I call ReactDom.render
in init()
only one g
tag is created and all circles are created inside this g
tag. but I want that on every ReactDom.render
call a separate g
tag must be created. My knowledge of components in React is that we can instantiate as many components as we want using React.createClass
. How can I do this?
var Rect = React.createClass({
render: function() {
return (
React.createElement('circle', {
cx: this.props.cx,
cy: this.props.cy,
r: this.props.r,
fill: '#00ff00'
});
);
}
});
var globalArray = [];
var someFunc = function(cx, cy, r) {
var Factory = React.createClass({
render: function() {
var localArray = [];
for(var i = 0; i < 1; i++) {
localArray[i] = React.createElement(Rect, {
key: globalArray.length,
cx: cx,
cy: cy,
r: r
})
}
globalArray[globalArray.length] = localArray[0];
return (
React.createElement('g', {}, globalArray)
)
}
});
return Factory;
}
var randomNumber = function (x,y) {
return ~~(Math.floor(((Math.random()*x) + y )));
}
var obj = {
init: function() {
var element;
for(var i = 0; i < 100; i++) {
var cx = randomNumber(1200,40);
var cy = randomNumber(600,40);
var r = randomNumber(30,20);
element = someFunc(cx,cy,r);
ReactDOM.render(
React.createElement(element,{}),
document.getElementById('svg')
);
}
}
}
You'll probably find that you benefit from letting the structure of your code be defined by React components, rather than your own functions and global variables.
Generally, if you find yourself calling ReactDOM.render
lots of times, then something has probably gone wrong.
Rather than rendering 100 components into one element, define a top level component which is made up of 100 subcomponent instances, then render that once.
var Graphics = React.createClass({
// ...
});
ReactDOM.render(
React.createElement(Graphics, null),
document.getElementById('svg')
);
We'll create a Graphics
component that we can use as a parent for the rest of the components. We only need to render this once .
Rather than storing your list of circles in a global array, use the state property on your new top level component. This way, whenever you update it, the component will re-render to reflect the changes.
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
allows us to define default values for the properties on this.state
and componentWillMount
allows to run code just before the component is rendered in the DOM.
Now that the Graphics component knows about the circles list, we have to describe the way it should be rendered.
render: function() {
var circles = this.state.circles.map(function(props) {
return React.createElement(Circle, props);
});
return React.createElement('g', null, circles);
}
This function uses map
to create a Circle
component using the props that we stored in this.state.circles
.
React is most effective when you structure your components to live within one top level container component, like we've created here. Rather than ever doing any imperative actions (like looping and rendering components each time) you should look for declarative alternatives.
React wants you to tell it what you want, not how it should be done.
In this case, what you wanted was a component with a number of randomly sized and positioned circles inside it, but what you tried to do was explain to React how it should go about making that happen.
var Circle = React.createClass({
render: function() {
// ...
}
});
var Graphics = React.createClass({
getInitialState: function() {
// ...
},
componentWillMount: function() {
// ...
},
render: function() {
// ...
}
});
The resulting code should not only be shorter and easier to follow, but also easy to refactor. Without much work you could move configuration details — like the number of circles — out to being a prop of Graphics
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.