当我按下按钮时,我试图将动态反应组件添加到其他反应组件中,现在我正在使用jQuery执行此操作,但代码很糟糕。主要的想法是当我按下时
<Button onClick={this.addProcess} data-mode="Hadoop"><Icon name="plus"/></Button>
该进程将附加在服务器中。这是由onClick={this.addProcess}
处理的,具有完成它的所有逻辑。
我的代码使用Jquery:
var React = require('react');
var ReactDOM = require('react-dom');
var {Icon} = require('react-fa');
var moment = require('moment');
var TimeAgo = require('react-timeago')
var {
ButtonGroup,
DropdownButton,
MenuItem,
Button,
Grid,
Row,
Col
} = require('react-bootstrap');
var ServerCanvas = React.createClass({
addProcess: function(event) {
// console.log(event.currentTarget.dataset.mode)
var process = event.currentTarget.dataset.mode;
var processDiv;
switch (process) {
case "Hadoop":
processDiv = ` <div class="Grid-cell Grid" style="flex-flow: column nowrap; background: linear-gradient(135deg, rgb(244, 143, 177) 0%, rgb(194, 24, 91) 100%);">
<div class="Grid-cell" style="font-size: 150%;">Hd</div>
<div class="Grid-cell" style="font-size: 75%;">Hadoop</div>
<div class="Grid-cell" style="font-size: 75%; color: rgb(0, 0, 0);">
</div>
</div>`;
break;
default:
}
var server = $('#servers').find('.test').not('.complete').first();
if (server.children().length < 3) {
server.append(processDiv); ///Append the new process
if (server.first().children().length === 3) {
server.addClass('complete');
}
}
},
render: function() {
return (
<div className="">
<Grid className="no-margin-padding container-hack">
<Row>
<Col md={4} className='grey-box'>
<Row className="rowHeight">
<Col md={6} className='text-center rowButton_Mid_Height'>
<div className="pull-right">
<Button bsClass='btn btn-default btn-lg btn-round' onClick={this.addServer}><Icon name="plus"/></Button>
<div>Add server</div>
</div>
</Col>
<Col md={6} className='text-center rowButton_Mid_Height'>
<div className="pull-left">
<Button bsClass='btn btn-default btn-lg btn-round' onClick={this.removeServer}><Icon name="minus"/></Button>
<div>Destroy Server</div>
</div>
</Col>
</Row>
</Col>
<Col md={8} className='black-box'>
<h1>Server Canvas</h1>
<div id='servers' className="serverContainer">
<div className="test grey-box">
<div className='text-center'>Server 0</div>
</div>
</div>
</Col>
</Row>
<Row>
<Col xs={4} md={4} className=''>
<Row>
<Col xs={12} md={12} className=''>
<div>
<div className='HadoopBackground pull-left'>
</div>
Hadoop
<div className='pull-right'>
<Button bsClass='btn btn-default btn-xs btn-round HadoopBackgroundButton'><Icon name="minus"/></Button>
<Button bsClass='btn btn-default btn-xs btn-round HadoopBackgroundButton' onClick={this.addProcess} data-mode="Hadoop"><Icon name="plus"/></Button>
</div>
</div>
</Col>
</Row>
</Col>
</Row>
</Grid>
</div>
)
}
});
ReactDOM.render(
<ServerCanvas/>, document.getElementById('app'));
但我正在寻找的是创建其他反应组件(在下面的代码中命名为Process),当我按下按钮并触发addProcess
时插入Process组件(删除了一些代码):
var Process = React.createClass({
render: function() {
return (
<div className="Grid-cell Grid">
<div className="Grid-cell" >Hd</div>
<div className="Grid-cell" >Hadoop</div>
<div><time className='loaded timeago'></time></div>
<div className="Grid-cell" >
</div>
</div>
);
}
})
addProcess: function(event) {
// console.log(event.currentTarget.dataset.mode)
var process = event.currentTarget.dataset.mode;
var processDiv;
var server = $('#servers').find('.test').not('.complete').first();
if (server.children().length < 3) {
console.log('puedo crear hijos');
server.append(<Process />); //Add the new process but nothing happend.
if (server.first().children().length === 3) {
server.addClass('complete');
}
}
}
答案 0 :(得分:1)
如果进行小幅调整以将当前服务器表示为状态中的数组,则可以迭代已添加的所有服务器。这是一个精简版本,用于演示如何实现这一目标:
var ServerCanvas = React.createClass({
// represent servers in state
getInitialState: function() {
return {
servers: []
}
},
// add new server to state
addService: function(event) {
this.setState({
servers: this.state.servers.concat(event.currentTarget.dataset.mode)
});
},
render: function() {
return (
<div>
<h3>Servers</h3>
<div className="servers">
{this.state.servers.map(function(server) {
return (
<div className="Grid-cell Grid" style="flex-flow: column nowrap; background: linear-gradient(135deg, rgb(244, 143, 177) 0%, rgb(194, 24, 91) 100%);">
<div class="Grid-cell" style="font-size: 75%;">{server}</div>
<div class="Grid-cell" style="font-size: 75%; color: rgb(0, 0, 0);">
</div>
</div>
)
})}
</div>
</div>
)
}
})
您还可以将服务器拆分为自己的组件:
var Server = React.createClass({
render: function() {
return (
<div className="Grid-cell Grid" style="flex-flow: column nowrap; background: linear-gradient(135deg, rgb(244, 143, 177) 0%, rgb(194, 24, 91) 100%);">
<div class="Grid-cell" style="font-size: 75%;">{this.props.serviceName}</div>
<div class="Grid-cell" style="font-size: 75%; color: rgb(0, 0, 0);">
</div>
</div>
)
}
})
并将ServerCanvas
渲染更改为:
{this.state.servers.map(function(server) {
return <Server serviceName={server} />;
})}
答案 1 :(得分:0)
您应该创建一个单独的组件并将其导入您的文件,例如ProcessComponent。
要添加它的多个位置,你应该在你的状态中有一个这样的组件数组,所以当你需要添加另一个时,只需将一个值推送到State中的这个数组,并使用setState来处理渲染和更新
渲染上的这样的东西:
render() {
var self = this;
//This "self" here is because inside the loop below, the "this" context is going to be Jquery and not your Class. So you keep it in a separated value just for refence purpose. Like passing a callBack as in the example.
var processComponent = this.state.processOnState.map(function(item, i)
{
return (
<Process key={"process"+i} ref={"process"+i} anyCallback={self.callBackMethodForParent.bind(self)} dataForProcess={item.dataToComponent} />
);
}.bind(this));
return (
<div>
<Col md={8} className='black-box'>
<h1>Server Canvas</h1>
<div id='servers' className="serverContainer">
<div className="test grey-box">
<div className='text-center'>Server 0</div>
</div>
{processComponent}
</div>
</Col>
</div>
)
因此,一旦更新数据,您可以使用以下命令触发更新:
setState({processOnState:[{dataToComponent:1},{dataToComponent:2}]})
默认情况下,react应该始终处理所有渲染和更新,它有一个逻辑运行在DOM中并找出已更改的内容,然后重新呈现它。您可以使用setState触发此行为,即点。
参考:https://facebook.github.io/react/docs/component-api.html#setstate