简体   繁体   English

如何在Reactjs中制作组件实例

[英]How to make component instances in Reactjs

When I call ReactDom.render in init() only one g tag is created and all circles are created inside this g tag. 当我在init()调用ReactDom.render ,仅创建一个g标签,并且在此g标签内创建所有圆。 but I want that on every ReactDom.render call a separate g tag must be created. 但我希望每次ReactDom.render调用都必须创建一个单独的g标签。 My knowledge of components in React is that we can instantiate as many components as we want using React.createClass . 我对React中组件的了解是,我们可以使用React.createClass实例化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. 您可能会发现,让代码结构由React组件定义,而不是由您自己的函数和全局变量定义,您将从中受益。

Generally, if you find yourself calling ReactDOM.render lots of times, then something has probably gone wrong. 通常,如果您发现自己多次调用ReactDOM.render ,则可能出了点问题。

Top Level Component 顶级组件

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. 而不是将100个组件渲染到一个元素中,而是定义一个由100个子组件实例组成的顶级组件,然后渲染一次。

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. 我们将创建一个Graphics组件,将其用作其余组件的父组件。 We only need to render this once . 我们只需要渲染一次

State

Rather than storing your list of circles in a global array, use the state property on your new top level component. 与其在全局数组中存储圈子列表,不如在新的顶层组件上使用state属性。 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. getInitialState允许我们为此属性定义默认值this.statecomponentWillMount允许在DOM中呈现组件之前运行代码。

Render 给予

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 . 该函数使用map使用存储在this.state.circles的道具创建一个Circle组件。

Conclusion 结论

React is most effective when you structure your components to live within one top level container component, like we've created here. 如您在此处创建的那样,当您将组件结构化以驻留在一个顶级容器组件中时,React最有效。 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. React希望您告诉它您想要什么 ,而不是应该怎么做。

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 . 无需进行大量工作,您就可以将配置详细信息(例如圈数)转移到Graphics的支持上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM