是否可以在重新渲染时更新className?
const [selected, setSelectedState] = useState(true);
let className = "none";
useEffect(() => {
className = "appointment-item " + (selected ? "selected" : "");
console.log(className );
}, [selected] );
return (
<div className={`${className}`} onClick={()=>setSelectedState(!selected)}>{Math.random()}</div>
);
控制台中的 className
可以正确显示,但是当div重新渲染时(我看到这是因为随机数更新了),className保持为“ none”。我也很困惑,因为我认为useEffect也可以立即运行..既然它应该马上被覆盖,那么它就永远不会被“无”了吗?
答案 0 :(得分:3)
不需要useEffect
,因为selected
已被定义为状态,因此您可以从selected
计算类名
const [selected, setSelectedState] = useState(true);
const className = "appointment-item " + (selected ? "selected" : "");
return (
<div className={className} />
)
答案 1 :(得分:3)
要添加有关@MarkoCen答案的更多详细信息(是正确的),使用挂钩时要了解的事情很少:
useEffect
在每个渲染后后运行。
在每个渲染中,在挂钩定义之后,组件从头开始重新执行。给定您的代码(我在每个周期添加注释以标识身份)
const [selected, setSelectedState] = useState(true); // 0
let className = "none"; // 1
useEffect(() => {
// 3
className = "appointment-item " + (selected ? "selected" : "");
console.log(className );
}, [selected] );
// 2
return (
<div className={`${className}`} onClick={()=>setSelectedState(!selected)}>{Math.random()}</div>
);
以下是循环的顺序:
第一个渲染:
0:useState
1:className = none
2:使用className = none渲染
3:useEffect
重新渲染:
1:className = none
2:使用className = none重新渲染
3:useEffect
如您所见,每个渲染器每次将className
设置为“无”,因此您将永远无法拥有期望的结果。
答案 2 :(得分:0)
如果要使用useState
,可以使用className
钩子为useEffect
变量来实现:
const [selected, setSelectedState] = useState(true);
const [className , setClassName] = useState("none");
useEffect(() => {
setClassName("appointment-item " + (selected ? "selected" : ""))
console.log(className );
}, [selected] );
return (
<div className={className} onClick={()=>setSelectedState(!selected)}>{Math.random()}</div>
);
但是我强烈建议@MarkoCen回复。
答案 3 :(得分:0)
您不需要为此使用useEffect。
您所需要的一切
const [selected, setSelectedState] = useState(true);
let clsName = 'appointment-item ' + (selected ? 'selected' : '');
return(
<div className={`${clsName}`} onClick={() => setSelectedState(!selected)}>
{Math.random()}
</div>
)