以下是HTML。
<script src="https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xtp1/t39.3284-6/12624079_897774290317920_1379776191_n.js"></script>
<script src="https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xfp1/t39.3284-6/12624052_751451571621845_431133942_n.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
<div class="row" id="container">
<div class="controls">
<span class="" id="controls-size">Size :
<button id="controls-size-small">SMALL</button>
<button id="controls-size-med">MEDIUM</button>
<button id="controls-size-large">LARGE</button>
</span>
</div>
<div id="game-container">
</div>
</div>
以下是Javscript
var SizeEnum = {
SMALL: 1,
MEDIUM: 2,
LARGE: 3
};
var Board = React.createClass({
getInitialState: function() {
return {
size: SizeEnum.MEDIUM
};
},
componentWillMount: function() {
if (this.state.size == SizeEnum.SMALL) {
this.style = {
width: 600 + 'px',
height: 320 + 'px',
margin: 'auto',
border: '2px solid red'
}
} else if (this.state.size == SizeEnum.MEDIUM) {
this.style = {
width: 700 + 'px',
height: 500 + 'px',
margin: 'auto',
border: '2px solid red'
}
} else if (this.state.size == SizeEnum.LARGE) {
this.style = {
width: 900 + 'px',
height: 720 + 'px',
margin: 'auto',
border: '2px solid red'
}
}
},
render: function() {
return ( < div style = {
this.style
} > < /div>
)
}
});
ReactDOM.render(<Board / > , document.getElementById("game-container"));
还有一些CSS
#game-container {
position: relative;
margin-top: 32px;
border: 1px solid black;
width: 100%;
}
我想要的是,当点击相应的按钮时,会将Board组件的大小调整为适当的大小。
我试过这样做
var board = ReactDOM.render(<Board />, document.getElementById("game-container"));
document.getElementById("controls-size-small").onclick = changeBoardSize;
document.getElementById("controls-size-med").onclick = changeBoardSize;
document.getElementById("controls-size-large").onclick = changeBoardSize;
function changeBoardSize(event) {
var etid = event.target.id;
console.log(etid);
if (etid == "controls-size-small") {
// method 1
board.state.size = SizeEnum.SMALL;
} else if (etid == "controls-size-med") {
// method 2
board.state.size = SizeEnum.MEDIUM;
ReactDOM.render(<Board />, document.getElementById("game-container"));
} else if (etid == "controls-size-small") {
// method 3
board.setState({size: SizeEnum.SMALL});
ReactDOM.render(<Board />, document.getElementById("game-container"));
}
}
但它没有用。
答案 0 :(得分:3)
您无法像这样设置React组件的状态。组件应负责设置自己的状态。
在Board组件中,在componentDidMount中设置事件侦听器。最好的解决方案是让按钮成为React应用程序的一部分,但这超出了这个问题的范围。所以我们假设按钮不是React应用程序的一部分,然后执行以下操作:
var Board = React.createClass({
...
...
componentDidMount: function(){
var that = this;
document.getElementById("controls-size-small").addEventListener('click', that.changeBoardSize, false);
document.getElementById("controls-size-med").addEventListener('click', that.changeBoardSize, false);
document.getElementById("controls-size-large").addEventListener('click', that.changeBoardSize, false);
}
changeBoardSize: function(e){
/* get the element id and do the enum things here */
this.setState({
size: newSize
});
}
render: function(){
...
...
}
});
然后将所有componentWillMount样式内容移动到render
函数。
更新
答案 1 :(得分:2)
你采取了错误的做法。关于反应的最难的部分是“反思中的思考”。如果你想让事情正常工作,那么直接进入DOM的概念,就像你正在使用document.getElementById一样,已不在桌面上。
最简单的方法是在Board组件的渲染功能中渲染按钮。然后,您可以在Board组件中放置一个单击处理程序来设置状态。
这应该让你开始:
handleClick: function (event) {
this.setState({ size: SizeEnum.SMALL });
},
render: function() {
return (
<div>
<div style = { this.style}></div>
<input type="button" onClick={this.handleClick}
</div>
)
}
一旦你开始工作,如果你想将按钮与按钮分开,那么你将需要考虑使用Flux实现来将状态从一个组件传递给组件。
答案 2 :(得分:1)
您不应直接更改React组件的状态。请改用setState功能。当你致电setState时,React将重新渲染组件。
将新功能setSize添加到您的Board组件:
var Board = React.createClass({
getInitialState: function() {
return {
size: SizeEnum.MEDIUM
};
},
setSize: function(size) {
this._setStyle(size);
this.setState({size: size});
},
_setStyle: fiunction(size) {
if (size == SizeEnum.SMALL) {
this.style = {
width: 600 + 'px',
height: 320 + 'px',
margin: 'auto',
border: '2px solid red'
}
} else if (size == SizeEnum.MEDIUM) {
this.style = {
width: 700 + 'px',
height: 500 + 'px',
margin: 'auto',
border: '2px solid red'
}
} else if (this.state.size == SizeEnum.LARGE) {
this.style = {
width: 900 + 'px',
height: 720 + 'px',
margin: 'auto',
border: '2px solid red'
}
}
},
componentWillMount: function() {
this._setStyle(this.state.size);
},
// ................
render: function() {
return ( <div style={this.style}></div>)
}
});
function changeBoardSize(event) {
var etid = event.target.id;
console.log(etid);
if (etid == "controls-size-small") {
board.setSize(SizeEnum.SMALL);
} else if (etid == "controls-size-med") {
board.setSize(SizeEnum.MEDIUM);
} else if (etid == "controls-size-small") {
board.setSize(SizeEnum.LARGE);
}
}
答案 3 :(得分:0)
这是一种反模式,尽管这是实现所需目标的正确方法。
由于ReactDOM.render返回呈现的组件的实例,您可以使用它并更新它的状态。
function changeBoardSize(event) {
var etid = event.target.id;
console.log(etid);
if (etid == "controls-size-small") {
board.setState({size: SizeEnum.SMALL});
} else if (etid == "controls-size-med") {
board.setState({size: SizeEnum.MEDIUM});
} else if (etid == "controls-size-small") {
board.setState({size: SizeEnum.LARGE});
}
}
正确的方法是制作Board的按钮组件并在其上附加事件处理程序,例如:
var Board = React.createClass({
getInitialState: function() {
return {
size: SizeEnum.MEDIUM
};
},
render: function() {
return (
<div>
<a href="#" onClick={this.onSizeChangeClick.bind(this, SizeEnum.SMALL)}>Small</a>
<a href="#" onClick={this.onSizeChangeClick.bind(this, SizeEnum.MEDIUM)}>Medium</a>
<a href="#" onClick={this.onSizeChangeClick.bind(this, SizeEnum.LARGE)}>Large</a>
</div>
)
},
onSizeChangeClick: function(size, event){
event.preventDefault();
this.setState({
size: size
});
}
})