将 onChange 绑定值反应到父级数组
react onChange bind value to array in parent
我是 React js 的新手,正在尝试构建一个简单的魔方游戏。我能够填充初始值。我一直在想办法让用户输入反映在父组件中。即在 Board class 的 handleChange(i) 方法中将空 Square 中输入的新值设置为 squares[i]。
class Square extends React.Component {
render()
{
return (
<input type="text" className="square" value={this.props.value} onChange={this.handleChange}>
</input>
);
}
}
/* Defines the Main Game Board */
class Board extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
/*Array to store Random numbers*/
const randArray = [];
for(var i = 0; i < 3; i++)
{
var numberIsInArray = false;
var rand = generateRandomNumb(1, 9);
for(var j = 0; j < randArray.length; j++){
if(rand === randArray[j]) {
numberIsInArray = true;
i--;
}
}
if(!numberIsInArray){
randArray.push(rand);
}
}
/*function to generate Random Numbers*/
function generateRandomNumb(min, max)
{
return Math.floor(Math.random() * (max - min) + min);
}
function check(grid_val, arr)
{
if (arr[0] === grid_val || arr[1] === grid_val || arr[2] === grid_val)
return grid_val;
}
this.state = {
squares: Array(
(4,check(4,randArray))
,(9,check(9,randArray))
,(2,check(2,randArray))
,(3,check(3,randArray))
,(5,check(5,randArray))
,(7,check(7,randArray))
,(8,check(8,randArray))
,(1,check(1,randArray))
,(6,check(6,randArray))
)
};
}
handleChange(i) {
const squares = this.state.squares.slice();
squares[i] = '';
//this.setState({squares: squares});
}
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onChange={this.handleChange(i)}
/>
);
}
render() {
const status = this.state.squares;
return (
<div>
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Sudoku React</h2>
</div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
<div>
<button onClick={() => window.location.reload()}>Start New Game</button>
</div>
</div>
);
}
}
export default Board;
这里有一些问题。
第 1 期
当您创建一个 <Square />
组件时,您将传递名为 value
和 onChange
的道具。但是在 Square 组件中,您正试图使用 this.handleChange
作为 onChange
处理程序。
this.handleChange
确实作为 Square
的 属性 存在。相反,您应该使用 Board
父级传递给它的 this.props.onChange
。
class Square extends React.Component {
// handleChange () {
// this is the none existant function referred to in the render function
// Instead: use this.props.onChange passed by the parent <Board />
// }
render()
{
return (
<input type="text" className="square" value={this.props.value} onChange={this.handleChange}>
</input>
);
}
}
这仍然无法工作,因为...
第 2 期
输入的 onChange
方法应该是一个函数。
问题 #1 解决后,Square 的 this.props.onChange
将变为 undefined
。
这是因为 handleChange
在我们作为 prop 传递时被调用(调用)。由于 handleChange
没有 return 值,我们传递 undefined
.
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onChange={this.handleChange(i)} // handleChange is being invoked! Note ()
/>
);
}
修复此问题所需的最少编辑是 handleChange
return 一个函数,它接受我们用来更新状态的事件。
handleChange (i) {
// Return ES6 bound function to maintain `this`
return (e) => {
const squares = this.state.squares.slice();
squares[i] = e.target.value; // The value of the input
this.setState({squares: squares});
};
}
P.s。一些额外的一般性评论;
renderSquare
应该在构造函数中绑定到 this
就像 handleChange
是
this.renderSquare = this.renderSquare.bind(this);
this.handleChange = this.handleChange.bind(this);
我还会将 generateRandomNumb
和 check
移出 <Board />
的构造函数,并将它们放在示例代码的最顶部,在任何 class
之外.
也把randArray
代移到一个函数里,也移到最上面
function generateRandArray () {
var randArray = [];
for(var i = 0; i < 3; i++)
{
var numberIsInArray = false;
var rand = generateRandomNumb(1, 9);
for(var j = 0; j < randArray.length; j++){
if(rand === randArray[j]) {
numberIsInArray = true;
i--;
}
}
if(!numberIsInArray){
randArray.push(rand);
}
}
return randArray;
}
并且在<Board />
的构造函数中
const randArray = generateRandArray();
我是 React js 的新手,正在尝试构建一个简单的魔方游戏。我能够填充初始值。我一直在想办法让用户输入反映在父组件中。即在 Board class 的 handleChange(i) 方法中将空 Square 中输入的新值设置为 squares[i]。
class Square extends React.Component {
render()
{
return (
<input type="text" className="square" value={this.props.value} onChange={this.handleChange}>
</input>
);
}
}
/* Defines the Main Game Board */
class Board extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
/*Array to store Random numbers*/
const randArray = [];
for(var i = 0; i < 3; i++)
{
var numberIsInArray = false;
var rand = generateRandomNumb(1, 9);
for(var j = 0; j < randArray.length; j++){
if(rand === randArray[j]) {
numberIsInArray = true;
i--;
}
}
if(!numberIsInArray){
randArray.push(rand);
}
}
/*function to generate Random Numbers*/
function generateRandomNumb(min, max)
{
return Math.floor(Math.random() * (max - min) + min);
}
function check(grid_val, arr)
{
if (arr[0] === grid_val || arr[1] === grid_val || arr[2] === grid_val)
return grid_val;
}
this.state = {
squares: Array(
(4,check(4,randArray))
,(9,check(9,randArray))
,(2,check(2,randArray))
,(3,check(3,randArray))
,(5,check(5,randArray))
,(7,check(7,randArray))
,(8,check(8,randArray))
,(1,check(1,randArray))
,(6,check(6,randArray))
)
};
}
handleChange(i) {
const squares = this.state.squares.slice();
squares[i] = '';
//this.setState({squares: squares});
}
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onChange={this.handleChange(i)}
/>
);
}
render() {
const status = this.state.squares;
return (
<div>
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Sudoku React</h2>
</div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
<div>
<button onClick={() => window.location.reload()}>Start New Game</button>
</div>
</div>
);
}
}
export default Board;
这里有一些问题。
第 1 期
当您创建一个 <Square />
组件时,您将传递名为 value
和 onChange
的道具。但是在 Square 组件中,您正试图使用 this.handleChange
作为 onChange
处理程序。
this.handleChange
确实作为 Square
的 属性 存在。相反,您应该使用 Board
父级传递给它的 this.props.onChange
。
class Square extends React.Component {
// handleChange () {
// this is the none existant function referred to in the render function
// Instead: use this.props.onChange passed by the parent <Board />
// }
render()
{
return (
<input type="text" className="square" value={this.props.value} onChange={this.handleChange}>
</input>
);
}
}
这仍然无法工作,因为...
第 2 期
输入的 onChange
方法应该是一个函数。
问题 #1 解决后,Square 的 this.props.onChange
将变为 undefined
。
这是因为 handleChange
在我们作为 prop 传递时被调用(调用)。由于 handleChange
没有 return 值,我们传递 undefined
.
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onChange={this.handleChange(i)} // handleChange is being invoked! Note ()
/>
);
}
修复此问题所需的最少编辑是 handleChange
return 一个函数,它接受我们用来更新状态的事件。
handleChange (i) {
// Return ES6 bound function to maintain `this`
return (e) => {
const squares = this.state.squares.slice();
squares[i] = e.target.value; // The value of the input
this.setState({squares: squares});
};
}
P.s。一些额外的一般性评论;
renderSquare
应该在构造函数中绑定到 this
就像 handleChange
是
this.renderSquare = this.renderSquare.bind(this);
this.handleChange = this.handleChange.bind(this);
我还会将 generateRandomNumb
和 check
移出 <Board />
的构造函数,并将它们放在示例代码的最顶部,在任何 class
之外.
也把randArray
代移到一个函数里,也移到最上面
function generateRandArray () {
var randArray = [];
for(var i = 0; i < 3; i++)
{
var numberIsInArray = false;
var rand = generateRandomNumb(1, 9);
for(var j = 0; j < randArray.length; j++){
if(rand === randArray[j]) {
numberIsInArray = true;
i--;
}
}
if(!numberIsInArray){
randArray.push(rand);
}
}
return randArray;
}
并且在<Board />
const randArray = generateRandArray();