我有一个3 * 3正方形的网格。
单击正方形时,我们将背景颜色更改为绿色。
因此,我尝试将所有状态放入父级GridContainer中。
__restrict__
这将保存被单击的索引。
state = {
gridCells: []
};
嵌套GridContainer
,网格嵌套Grid
。
Square
这是我当前的实现方式。
现在如何在重置点击时清除背景单元格并使背景再次变回白色?
render() {
return (
<div>
<Grid action={this.handler} />
<button>Reset Clicks</button>
</div>
);
}
因此,当我单击function Square(props) {
const liClickHandler = event => {
event.target.classList.add("highlight");
props.clickAction();
};
return <li onClick={e => liClickHandler(e)} />;
}
function Grid(props) {
const gridHandler = index => {
props.action(index);
};
return (
<ul>
{Array.from(new Array(9)).map((item, index) => (
<Square key={index} clickAction={() => gridHandler(index)} />
))}
</ul>
);
}
class GridContainer extends React.Component {
state = {
gridCells: []
};
handler = index => {
let temp = [...this.state.gridCells];
temp.push(index + 1);
this.setState({
gridCells: temp
});
};
render() {
return (
<div>
<Grid action={this.handler} />
<button>Reset Clicks</button>
</div>
);
}
}
时,它会调用方法Sqaure
并调用clickAction
更新状态,我们有一个数组,按顺序单击了索引。
如何实现handler
?我如何让我的孩子知道。
我维护状态错误吗?
沙盒链接:https://codesandbox.io/s/3-x-3-grids-s0b43?file=/src/index.js:640-1563
答案 0 :(得分:2)
我建议您重新考虑组件的结构方式。
每个组件应该是具有自己的逻辑和状态的独立单元(当然,如果需要的话)。我说的是如果需要状态,因为理想情况下组件应该是无状态的。
Square类存在几个问题:
这两个问题实际上导致您无法轻松重置正方形的显示。
我已经更新了您的示例:https://codesandbox.io/s/3-x-3-grids-uflhr?file=/src/index.js
它仍然不是理想的,但是您会注意到gridCells是通过props从顶部传递的。然后每个广场都有自己的道具参数。这允许状态通过流,并让正方形使用更新的类重新渲染。
答案 1 :(得分:1)
在做出反应时,您应该想到“反应”方式:
这里是演示的corrected version:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function Square(props) {
return (
<li onClick={props.onClick} className={props.active ? "highlight" : ""} />
);
}
function Grid(props) {
let squares = [];
for (let i = 0; i < 9; i++) {
squares.push(
<Square
key={i}
onClick={() => props.onCellClick(i)}
active={props.cells[i]}
/>
);
}
return <ul>{squares}</ul>;
}
class GridContainer extends React.Component {
state = {
gridCells: []
};
onCellClick = index => {
this.setState(prevState => {
const newCells = [...prevState.gridCells];
newCells[index] = true;
return {
gridCells: newCells
};
});
};
render() {
return (
<div>
<Grid cells={this.state.gridCells} onCellClick={this.onCellClick} />
<button
onClick={() => {
let that = this; //we could bind the callback aswell
that.setState(() => ({ gridCells: [] }));
}}
>
Reset Clicks
</button>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<GridContainer />, rootElement);