useState 初始值未设置

时间:2021-04-12 20:17:25

标签: javascript reactjs

以下是我的要求的简化版本,足以重现问题。组件 ColorBoxShowColorComponent 接收一个 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.logs 的输出显示如下?

false
true

既然我把 isVisible 的值设置为初始值,那么 visible 怎么会是假的?

这是 CodeSandbox 示例 https://codesandbox.io/s/react-state-issue-sc58k

2 个答案:

答案 0 :(得分:2)

如果您的问题是为什么 visibleisVisible 不同,那是因为 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 时,isVisiblefalse,这也会使 visible false 为好。但是当您点击时,它不会调用 setVisible。所以 visible 仍然是 false,但点击确实调用了 setIsVisible,从而将 isVisible 变成了 true