繁体   English   中英

无法使用 forwardRef 设置组件样式

[英]Unable to style component using forwardRef

我对反应还很陌生,所以我仍然了解组件的生命周期。 但这个问题让我摸不着头脑。

例如,我不明白为什么要添加“setState(10);” 导致“测试”组件的样式恢复为默认值,但<div ref={ref2}>Hi</div>保持其样式。 (见下图)

我知道“setState(10);” 会导致重新渲染,但为什么要恢复“测试”组件的样式?

另外,请忽略调用 setState(10) 的“实际使用”——我知道它毫无意义,因为它从未被使用过,而且我知道使用“state”作为 UseEffect 依赖项可以解决这个问题。 但我遇到的主要问题是理解为什么组件的样式会恢复为默认值。

import React, { useEffect, useState, useRef } from "react";

export default function App() {
  const [state, setState] = useState();
  let ref1 = useRef();
  let ref2 = useRef();
  useEffect(() => {
    console.log("useEffect called ", ref1.current);
    ref1.current.style.backgroundColor = "red";
    ref2.current.style.backgroundColor = "green";
    setState(10);
   // }, [state]);
  }, []);

  const Test = React.forwardRef((props, ref1) => {
    console.log("test called - rendering webpage", ref1.current);
    return (
      <div ref={ref1} {...props}>
        HI from Test{" "}
      </div>
    );
  });

  return (
    <div className="App">
      <Test ref={ref1} />
      <div ref={ref2}>Hi</div>
    </div>
  );
}

控制台 output

test called - rendering webpage undefined
useEffect called <div style="background-color: red;">HI </div>
test called - rendering webpage <div style="background-color: red;">HI </div>

在此处输入图像描述

import React, { useEffect, useState, useRef } from "react";

export default function App() {
  const [state, setState] = useState();
  let ref1 = useRef();
  let ref2 = useRef();
  useEffect(() => {
    console.log("useEffect called ", ref1.current);
    ref1.current.style.backgroundColor = "red";
    ref2.current.style.backgroundColor = "green";
    setState(10);
    // }, [ref.current]);
  }, [state]);

  const Test = React.forwardRef((props, ref1) => {
    console.log("test called - rendering webpage", ref1.current);
    return (
      <div ref={ref1} {...props}>
        HI from Test{" "}
      </div>
    );
  });

  return (
    <div className="App">
      <Test ref={ref1} />
      <div ref={ref2}>Hi</div>
    </div>
  );
}

发生这种情况的原因是一旦您更新 state 整个组件就会重新呈现。 您的 useEffect 将仅在 componentDidMount 上运行一次,因此您获得的新参考不会更新。 要摆脱这种情况,您应该使用 state 作为 useEffect 的依赖项。

样式消失的原因是您已经App组件中定义了Test组件。 这意味着每次App呈现时,您都将定义一个名为Test的新组件类型。 该组件的文本与前一个组件相同,但就 React 而言它是一种新类型,因此 React 被迫卸载旧组件并安装新组件。 这会清除您对旧版本所做的任何更改。

所以至少,您需要将Test移到App之外。 这样,组件只定义一次,不会在每次渲染时重新挂载

export default App() {
  // ...
}

const Test = React.forwardRef((props, ref1) => {
  // ...
})

上面应该修复重置并让您尝试使用 refs,但我强烈建议您不要使用 refs 来设置元素的样式。 Refs 是有时需要的逃生舱口,但为组件设置样式的标准方法是通过 style 道具。 如果你需要改变风格,那么你可以有一个 state 变量,让它控制风格道具。

如果您手动使用 javascript 设置ref1.current.style.backgroundColor ,react 无法知道您这样做了,因此无法将这些更改考虑在内。 在某些情况下,React 可能最终会覆盖您的更改,或者可能会跳过它没有意识到需要做的更改。

export default function App () {
   const [colored, setColored] = useState(false);
   useEffect(() => {
     setColored(true);
   }, [])

   return (
    <div className="App">
      <Test style={colored ? { backgroundColor: "green" } : undefined} />
      <div style={colored ? { backgroundColor: "red" } : undefined}>Hi</div>
    </div>
  );
}

// Don't really need forwardRef anymore, but i left it in
const Test = React.forwardRef((props, ref) => {
  return (
    <div ref={ref} {...props}>
      HI from Test
    </div>
  );
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM