以下是我的要求的简化版本,足以重现问题。组件 ColorBox
从 ShowColorComponent
接收一个 prop,用于设置 ColorBox.visible
状态的初始值。
import React, { useState } from "react";
export const Container = ({ Component }) => {
return (
<>
<Component />
</>
);
};
export const ShowColorComponent = () => {
const [isVisible, setIsVisible] = useState(false);
const handleClick = () => {
setIsVisible(!isVisible);
};
return (
<>
<button onClick={handleClick}>click</button>
<ColorBox isVisible={isVisible} />
</>
);
};
export const ColorBox = ({ isVisible }) => {
const [visible, setVisible] = useState(isVisible);
console.log(visible);
console.log(isVisible);
return (
<div
style={{
widht: "50px",
height: "50px",
backgroundColor: "red",
display: `${visible ? "block" : "none"}`
}}
></div>
);
};
App.js
import React from "react";
import ReactDOM from "react-dom";
import { Component, ShowColorComponent } from "./demo";
ReactDOM.render(
<Component ShowColorComponent={ShowColorComponent} />,
document.querySelector("#root")
);
我可能应该使用一种方法来设置父级的 ShowColorComponent.isVisible
,而不是在 ColorBox
中重新定义新状态。但是为什么我第一次点击按钮时,console.log
s 的输出显示如下?
false
true
既然我把 isVisible
的值设置为初始值,那么 visible
怎么会是假的?
这是 CodeSandbox 示例 https://codesandbox.io/s/react-state-issue-sc58k
答案 0 :(得分:2)
如果您的问题是为什么 visible
和 isVisible
不同,那是因为 useState 仅在第一次呈现 React 组件时运行。 (直到卸载并再次安装)。
如果您想在每次更改时跟踪任何变量的更改,请使用 useEffect 钩子,如下所示:
useEffect(() => {
setVisible(isVisible);
}, [isVisible]);
在你的情况下,你可以删除
const [visible, setVisible] = useState(isVisible);
行并在您的显示中使用您父母的 isVisible:
display: `${isVisible ? "block" : "none"}`
甚至根本不使用 && 运算符渲染 div。
return (
isVisible &&
<div
style={{
widht: "50px",
height: "50px",
backgroundColor: "red"
}}
></div>
);
答案 1 :(得分:1)
当您渲染 ColorBox
时,isVisible
为 false,这也会使 visible
false 为好。但是当您点击时,它不会调用 setVisible
。所以 visible
仍然是 false,但点击确实调用了 setIsVisible
,从而将 isVisible
变成了 true。