我有一个反应函数来处理表单提交
handleSubmit(e){
this.setState({size: this.state.value});
this.setState({maze : <Maze size={this.state.value}></Maze>}, () => this.forceUpdate());
console.log('set state finished');
e.preventDefault();
}
在具有以下
的app类中 render() {
return (
<div className="App">
<form onSubmit={this.handleSubmit}>
<label>Size: </label>
<input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input>
<input type="submit" value="Generate Maze"></input>
</form>
{this.state.maze}
</div>
);
}
但是代码并没有让迷宫重新回归; 需要注意的两件事
我在setState回调中放了一个警告,它弹出(意思是,我认为,setState完成了,应该有一个rerender)并在没有重新渲染的情况下传递
强制更新回调不起作用
我该如何解决这个问题?
Main类的完整代码
class App extends Component {
constructor(props){
super(props);
this.state = {
size : 20,
value : 20,
showMaze : false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount(){
this.setState({maze : <Maze size={this.state.size}></Maze>});
}
handleChange(e){
this.setState({value : e.target.value});
}
handleSubmit(e){
this.setState({size: this.state.value});
this.setState({showMaze: false});
this.setState({maze : <Maze size={this.state.value}></Maze>}, () => this.forceUpdate());
this.setState({showMaze: true});
e.preventDefault();
}
render() {
return (
<div className="App">
<form onSubmit={this.handleSubmit}>
<label>Size: </label>
<input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input>
<input type="submit" value="Generate Maze"></input>
</form>
{this.state.showMaze? this.state.maze : null}
</div>
);
}
}
Maze类的完整代码(减去生成算法)
class Maze extends Component{
constructor(props){
super(props);
this.state = {
size : this.props.size,
maze : null
}; //declare the maze null for now
}
componentDidMount(){
this.generateMazev2(this.props.size);
}
generateMazev2 (size){
//snippped
}
render(){
var renderMaze = new Array(); //store the table
//calculate the percentage size of each Cell
var size = 80.0 / this.props.size; //the table should ideally take up 80% of the page
if(this.state.maze !== null){
this.state.maze.forEach(function (row, index, arr){
var newRow = new Array();
row.forEach(function (box, theIndex, arr){
newRow[theIndex] = <Cell size={size} top={box.top} bottom={box.bottom} right={box.right} left={box.left}></Cell>;
});
renderMaze[index] = <tr>{newRow}</tr>;
});
return (<table>{renderMaze}</table>);
}else{
return (<p>Generating</p>);
}
}
}
答案 0 :(得分:0)
您可以做的一件事是更改render()方法,如下所示。
render() {
return (
<div className="App">
<form onSubmit={this.handleSubmit}>
<label>Size: </label>
<input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input>
<input type="submit" value="Generate Maze"></input>
</form>
{this.state.showMaze? <Maze size={this.state.value}></Maze> : null}
</div>
);
}
之后修改handleSubmit()方法,如下所示
handleSubmit(e){
this.setState({size: this.state.value, showMaze: true});
console.log('set state finished');
e.preventDefault();
}
<强>更新强>
将组件保持为状态属性不是一个好习惯。因此,在我已经显示的渲染方法中替换{this.state.showMaze? this.state.maze : null}
行。
此外,您需要在Maze组件中实现componentWillReceiveProps()方法并根据新的props修改其状态。
componentWillReceiveProps(nextProps) {
this.setState({size: nextProps.size})
}
答案 1 :(得分:0)
这不是正确的方法,UI组件不应存储在状态值中。国家应该只包含数据。
<强>解决方案:强>
在状态变量中保持bool并使用该bool进行Maze组件的条件渲染,bool的初始值将为false并更新handleSubmit(e){
e.preventDefault();
this.setState({size: this.state.value, showMazeCom: true});
}
render() {
return (
<div className="App">
<form onSubmit={this.handleSubmit}>
<label>Size: </label>
<input type="number" min="3" step="1" onChange={this.handleChange} value={this.state.value}></input>
<input type="submit" value="Generate Maze"></input>
</form>
{this.state.showMazeCom && <Maze size={this.state.value}></Maze>}
</div>
);
}
函数内的bool。
像这样:
shouldComponentUpdate(nextProps){
if(nextProps.size != this.props.size)
return true;
return false;
}
更新:
为避免不必要的重新发送迷宫组件,请使用 shouldComponentUpdate 生命周期方法,比较新旧道具值,如果它们不相同则只允许重新渲染
像这样:
{{1}}