[英]React render vs. UseState
我对此很陌生,无法真正弄清楚渲染是如何工作的 - 现在坚持使用 UseState :) -。 因为我看到很多人在使用它,所以我想就我做错了什么征求意见。 这里有 2 个示例,一个使用 UseState 效果很好,另一个使用 render 什么都不做,我添加了一些样式,所以它看起来对于任何尝试它的人来说都是可以接受的。
任何帮助表示赞赏,谢谢
// 使用状态
const [newColor, setNewColor] = useState('green');
useEffect(() => {
setBorder()
}, [newColor])
function setBorder() {
if (newColor === 'green') {
document.getElementById('green').style.borderColor = "orange";
document.getElementById('yellow').style.borderColor = "black";
document.getElementById('red').style.borderColor = "black";
}
if (newColor === 'yellow') {
document.getElementById('yellow').style.borderColor = "orange";
document.getElementById('green').style.borderColor = "black";
document.getElementById('red').style.borderColor = "black";
}
if (newColor === 'red') {
document.getElementById('red').style.borderColor = "orange";
document.getElementById('green').style.borderColor = "black";
document.getElementById('yellow').style.borderColor = "black";
}
}
const changeBg = () => {
document.body.style.backgroundColor = newColor;
}
return (
<div>
<div style={{width: '240px', height: '88px', border: '3px solid black', 'borderRadius': '10px'}}>
<div id="green" onClick={(e) => setNewColor(e.target.id)} style={{width: '40px', height: '40px', background: 'green', border: '3px solid black', float: 'left', margin: '20px 0 0 30px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
<div id="yellow" onClick={(e) => setNewColor(e.target.id)} style={{width: '40px', height: '40px', background: 'yellow', border: '3px solid black', float: 'left', margin: '20px 0 0 20px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
<div id="red" onClick={(e) => setNewColor(e.target.id)} style={{width: '40px', height: '40px', background: 'red', border: '3px solid black', float: 'left', margin: '20px 0 0 20px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
</div>
<button onClick={changeBg}>SAVE</button>
</div>
);
// 使成为
class Test1 extends Component {
constructor(props) {
super(props);
this.state = {
newColor: 'green'
}
}
componentDidUpdate() {
if (this.newColor === 'green') {
document.getElementById('green').style.borderColor = "orange";
document.getElementById('yellow').style.borderColor = "black";
document.getElementById('red').style.borderColor = "black";
}
if (this.newColor === 'yellow') {
document.getElementById('yellow').style.borderColor = "orange";
document.getElementById('green').style.borderColor = "black";
document.getElementById('red').style.borderColor = "black";
}
if (this.newColor === 'red') {
document.getElementById('red').style.borderColor = "orange";
document.getElementById('green').style.borderColor = "black";
document.getElementById('yellow').style.borderColor = "black";
}
}
render() {
const changeBg = () => {
document.body.style.backgroundColor = this.newColor;
}
return (
<div>
<div style={{width: '240px', height: '88px', border: '3px solid black', 'borderRadius': '10px'}}>
<div id="green" onClick={(e) => this.state={newColor: e.target.id}} style={{width: '40px', height: '40px', background: 'green', border: '3px solid black', float: 'left', margin: '20px 0 0 30px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
<div id="yellow" onClick={(e) => this.state={newColor: e.target.id}} style={{width: '40px', height: '40px', background: 'yellow', border: '3px solid black', float: 'left', margin: '20px 0 0 20px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
<div id="red" onClick={(e) => this.state={newColor: e.target.id}} style={{width: '40px', height: '40px', background: 'red', border: '3px solid black', float: 'left', margin: '20px 0 0 20px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
</div>
<button onClick={changeBg}>SAVE</button>
</div>
);
}
}
首先,你永远不应该像你一样在react中直接更新 DOM。 在这两个示例中,您都在这样做。 第二个示例不起作用的原因, componentDidUpdate
在更新发生时调用(例如状态更改或道具更改),这不会发生,因为您没有在第二个示例中调用setState
; 而是直接分配给this.state
。 如评论中所述,它也应该是this.state.newColor
。
在反应中解决这个问题的惯用方法是:
export default function App() {
const [newColor, setNewColor] = React.useState('green');
const changeBg = () => {
document.body.style.backgroundColor = newColor;
};
return (
<div>
<div
style={{
width: '240px',
height: '88px',
border: '3px solid black',
borderRadius: '10px',
}}
>
{['green', 'yellow', 'red'].map((x) => (
<div
onClick={(e) => setNewColor(x)}
style={{
width: '40px',
height: '40px',
background: x,
border: '3px solid black',
borderColor: newColor === x ? 'orange' : 'black',
float: 'left',
margin: '20px 0 0 30px',
borderRadius: '10px',
cursor: 'pointer',
}}
></div>
))}
</div>
<button onClick={changeBg}>SAVE</button>
</div>
);
}
虽然现在盒子没有很好地居中,因为当所有div
都是手工写出时,第一个元素的边距不同。 但是现在我对所有这些都有相同的余量,因为我使用了一个循环。 我会让你来调整它。
*在 极少数情况下你可以,当说与 3rd 方库集成时,但在这种情况下,你应该确保 react 不会触及 DOM 的那部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.