【问题标题】:React: setState to a single component from multiple mapped instances of the same component反应:从同一组件的多个映射实例中将状态设置为单个组件
【发布时间】:2021-09-12 06:40:54
【问题描述】:

我有一个悬停状态,它会更改 div 背景颜色并将<p> 标签添加到映射组件:

const [isHover, setIsHover] = useState(false)

这是我设置状态的映射组件:

const AddSectionButton = ({
  isHover,
  setIsHover,
  sections,
  setSections,
  nextSectionId,
  setNextSectionId,
  sectionTitle,
  setSectionTitle,
  sectionId,
}) => {
  return (
    <AddSectionDiv
      onMouseEnter={() => {
        setIsHover(!isHover);
      }}
      onMouseLeave={() => {
        setIsHover(!isHover);
      }}
      style={isHover && { backgroundColor: "#A4AAE0" }}
    >
      {isHover && <p>Add Section</p>}
    </AddSectionDiv>
  );
};

每当我将鼠标悬停到单个映射组件时,其余映射组件也会触发悬停效果。

如何将状态设置为仅悬停的组件而不影响其余组件?

我考虑过使用密钥,正如您在我的映射组件中看到的那样,我传递了一个包含密钥的 sectionId 道具,但我对如何使用它感到困惑。

【问题讨论】:

  • 每个映射的组件可能应该管理自己的状态。目前,当一个组件(在父组件中)设置状态时,所有组件都以相同的状态呈现。
  • 我同意@Andy。这也是最佳实践的一部分,否则应用程序管理会变得一团糟。否则,德鲁提供的答案应该可以解决问题。

标签: javascript reactjs react-hooks use-state


【解决方案1】:

您可以并且应该使用唯一标识被悬停的元素的键或任何值/属性。

在父级中使用初始为 null 的 isHover 状态。

const [isHover, setIsHover] = useState(null);

在孩子们通过他们的 id 设置或清除 isHover 状态。并检查当前的isHover 值是否与当前的sectionId 值匹配。

const AddSectionButton = ({
  isHover,
  setIsHover,
  sections,
  setSections,
  nextSectionId,
  setNextSectionId,
  sectionTitle,
  setSectionTitle,
  sectionId,
}) => {
  return (
    <AddSectionDiv
      onMouseEnter={() => {
        setIsHover(sectionId);
      }}
      onMouseLeave={() => {
        setIsHover(null);
      }}
      style={isHover === sectionId && { backgroundColor: "#A4AAE0" }}
    >
      {isHover === sectionId && <p>Add Section</p>}
    </AddSectionDiv>
  );
};

考虑在每个组件内部移动/实现此isHover 状态,父组件可能不需要关注其任何子组件的悬停状态。这样做,您的原始逻辑就可以了。

const AddSectionButton = ({
  sections,
  setSections,
  nextSectionId,
  setNextSectionId,
  sectionTitle,
  setSectionTitle,
  sectionId,
}) => {
  const [isHover, setIsHover] = useState(false);

  return (
    <AddSectionDiv
      onMouseEnter={() => {
        setIsHover(true);
      }}
      onMouseLeave={() => {
        setIsHover(false);
      }}
      style={isHover && { backgroundColor: "#A4AAE0" }}
    >
      {isHover && <p>Add Section</p>}
    </AddSectionDiv>
  );
};

【讨论】:

    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 2016-12-07
    • 2018-03-19
    • 2020-04-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    相关资源
    最近更新 更多