更新useEffect“每次重新渲染后丢失”问题的JSX变量

时间:2020-03-21 05:54:20

标签: reactjs jsx

我一直在尝试根据情况添加可选的JSX,因此我将它们初始化为null,并在适当的时候更新了它们,以便它们包含JSX。

//initialize potentially unused parts
let monitor = null;
let keyboard = null;

...

稍后在我的JSX中,我仅使用这些信息来显示信息。

{monitor}
{keyboard}

我做了一些研究,发现我的状态没有更新,因为useState是异步的,所以我设置了useEffect钩子,试图在状态最终更新时更新这些变量。

const [monitorState, setMonitorState] = useState(0);
const [keyboardState, setKeyboardState] = useState(0);

useEffect(() => {
    monitor = (
        <li>
            <span className="bold">Monitor: </span>
            {monitorState.title}}
            <span className="right">${monitorState.price}</span>
        </li>
    );
}, [monitorState]);

const handler = (item) => {
    if (item.type === "monitor") {
        setMonitorState(item);
    }
    ...
}

在模式组件中单击添加按钮时,将调用此处理程序:

<a
   onClick={() => props.handler(item)}
   href="#!"
   className="modal-close btn waves-light waves-effect grey darken-3 
   white-text modal-item-add">
   Add
</a>

但是,我得到一个错误:

在每个渲染之后,从React Hook useEffect内部分配给'monitor'变量的分配将丢失。要随时间保留该值,请将其存储在useRef Hook中,并将可变值保留在'.current'属性中。否则,您可以直接在useEffect内部移动此变量。

我很困惑useRef将如何解决此问题,以及在给定问题的情况下如何实现该问题。我看过其他线程,但是更新JSX变量都没有完成。

2 个答案:

答案 0 :(得分:2)

每次重新发布功能组件时,底层的React代码都会再次调用该函数。在这种重新渲染中会发生的是,函数中的所有变量都将被重新初始化,除了状态和引用外,因为它们分别由React分别存储。

按照建议的立场,让我们看一下如何使用参考来更正此问题:

const monitorRef = useRef(null);

useEffect(() => {
    monitorRef.current = (
        <li>
            <span className="bold">Monitor: </span>
            {monitorState.title}}
            <span className="right">${monitorState.price}</span>
        </li>
    );
}, [monitorState]);

return (
  <div>{monitorRef.current}</div>
)

此处ref值与React一起存储,因此在重新渲染时不会被破坏。

但是,从您共享的代码中,您似乎可以将monitor代码添加到render中:

const [monitorState, setMonitorState] = useState(null);

const handler = (item) => {
    if (item.type === "monitor") {
        setMonitorState(item);
    }
    ...
}

return monitorState ? (
  <li>
     <span className="bold">Monitor: </span>
     {monitorState.title}}
     <span className="right">${monitorState.price}</span>
  </li>
) : null;

答案 1 :(得分:0)

您可以将useRef视为一个可变对象,该对象会在每次渲染时记住其值。它的值始终存储在current属性中。因此,您可以通过以下方式解决您的问题:

const monitor = useRef(null)
在您的useEffect中:
monitor.current = ( <li>...</li> )

以上是使用useRef解决问题的一种方法,但我觉得有些困惑。我认为使用javascript的&&运算符可以轻松解决此问题。

在您的JSX中,只需输入:

{monitorState?.title && monitorState?.price &&
  <li>...</li>
)}

当然,如果您想真正准确,可以检查titleprice是否也未定义,因为它们分别是空字符串和0。

相关问题