我一直在尝试根据情况添加可选的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变量都没有完成。
答案 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>
)}
当然,如果您想真正准确,可以检查title
和price
是否也未定义,因为它们分别是空字符串和0。