javascript - 使用 React “useState”,当对象中的值更新时,即使某些值没有更改,也会重新渲染附加到状态的所有内容
问题描述
我想做什么?
当我只更新一个值而其他值保持不变时,在调整对象状态时停止重新渲染。
当前尝试执行此操作的代码是什么?
呈现信息的前端组件:
export default function ReactComponent() {
const [characterState, setCharacterState] = useState(data.character);
useEffect(() => {
socket.emit("/character/read");
socket.on("/character/read", function (data) {
if (data.status === "SUCCESS") {
setCharacterState(data);
}
});
return () => {
socket.off("/character/read");
};
}, []);
return (
<div>
Name: {characterState.name}
Stand: {characterState.stand}
Status: {characterState.status}
</div>
)
}
作为“数据”的后端.json
信息以及保存到characterInfo
的内容setCharacterInfo
:
{
status: "SUCCESS"
character: {name: "Dio", stand: "The World", status: "Alive"};
}
我期望结果是什么?
如果后端在“/character/read”上发送了一些新内容,请说:
// Status is now "Dead".
{
status: "SUCCESS"
character: {name: "Dio", stand: "The World", status: "Dead"};
}
我希望在 React 函数中只重新渲染状态。
实际结果是什么?
尽管对象中的其他值没有更新,但整个状态被重新渲染(可以看到调整的值)。
我认为问题可能是什么?
我认为它与“useState”有关,“useState”不关心是否有一些改变、全部改变或没有改变的值,“useState”总是会重新渲染它给出的任何东西。我在想一个可能的解决方案是为“characterName”、“characterStand”和“characterStatus”制作 3 个单独的状态,但寻找是否有另一种替代方法来尝试仅尝试 1 个状态。
编辑:
我未能传达我想要实现的目标,但 Sajeeb 所说的正是我最终想要的。
如果属性(在这种情况下为“characterState.status”)发生变化,我希望重新渲染“characterState.status”而不是“characterState.name”或“characterState.stand”。由于 React 的默认行为,所有这些 1 状态下的属性都会导致它们中的每一个都重新渲染,因为状态“characterState”本身已更新。
谢谢大家的帮助。
解决方案
我实际上建议您保持原样。
推理:
你现在拥有的:
- 1 个 API 调用
- 1 个组件
- 1 一种状态管理
由于您存储的数据characterState
非常小,因此将其分解或担心可能的重新渲染确实没有任何意义。
在任何其他情况下,您最终会得到一个不太干净且性能较低的代码。
例如,如果您尝试useState
在一个组件中将其分解为三个 s,那么您现在需要管理 3 个状态,并且您还没有解决重新渲染的问题。
如果您对状态使用三个不同的组件,您将拥有:
- 3 API 调用
- 3 个组件
- 3 个状态来管理
和不太干净的代码。
一切都是为了解决一个不是真正问题的问题
在您提供的情况下,我肯定会建议保持原样。
除非您有一些非常具体的原因,否则它不能很好地工作。
推荐阅读
- php - 为什么在布尔值上执行()时出错,尝试绑定和关闭?
- java - 如何修复 io.vertx.core.impl.NoStackTraceThrowable?
- python - 如何在 sql 中查询以重新格式化查询集
- c++ - 我可以在 React Native for Windows 中使用 OpenGL 上下文吗?
- c - 关于删除链表中节点的问题
- mysql - MySQL中第一个带参数的存储过程
- c++ - C++ 在计算余弦时总是返回 -inf
- jquery - TypeError: window.$(...).modal 不是函数
- split - 如何使用 split() 从 foreach 循环显示多行数据输出到单个 textview
- google-authentication - java.io.IOException:从流中读取凭据时出错,未指定“类型”字段