React material-ui 对话框出现奇怪的重新渲染行为
Weird re-render behavior with react material-ui dialog
背景
所以我基于 React 和 Material UI 构建了一个交付服务的前端项目。
我被要求使用一个 Dialog window,它会在单击项目时打开,用户将有机会自定义该项目。
对话框可以在这里看到(非常简单:项目照片、名称、描述和自定义选项):
(抱歉像素化)
问题
我在这个项目中使用了反应钩子,这就是为什么要管理对话框的状态。
虽然简单,但我偶然发现了元素如何 re-rendered/not 重新渲染(预期时)的一些问题:
- 复选框的
"checked"
属性使用Array.some
,查看复选框的唯一ID是否在状态数组中。单击复选框时,复选框未设置为已选中。 onChange
道具只是将复选框的值推送到状态数组并设置状态:
const [array, setArray] = React.useState([]);
...
<Checkbox
checked={
array.some(
item => item._id === subOption._id
)
}
onChange={() => setArray(array.push(subOption))}
/>
onChange
动作正常,那么为什么 "checked"
道具不能正常工作?
- 选中一个复选框后,我想在它旁边添加一个小数量字段,这样用户就可以选择他要接收的
subOption
数量。
所以我使用下一个熟练的模式:
{array.some(item => item._id === subOption._id) &&
(
<QuantityField />
)
}
问题是选中复选框后未显示 QuantityField。
如果我退出Dialog再进入,突然看到checked的checkbox被选中了,旁边显示QuantityField
如果我使用您可以在对话框图像左下方看到的通用 QuantityField 更改项目的数量,突然所有选中的复选框都被取消选中
一般的 QuantityField 使用它自己的状态,并且没有连接到任何复选框。
根据我尝试调试奇怪行为后所见,我可以说 Dialog 组件的呈现操作未按预期工作。状态已更新,但不会触发对话树的重新呈现。实际上,这样说是错误的,因为 Dialog 树被重新渲染,但是在重新渲染期间没有重新检查“checked”prop;但是完全卸载并重新安装对话框会使树向右摇晃。
希望得到一个有趣的答案。谢谢。
我会改变您的使用方式 setArray
。参见 Array.prototype.push()
文档:
The push()
method adds one or more elements to the end of an array and returns the new length of the array.
也不允许在状态上使用 .push()
,因为 永远不应该直接改变状态。
建议的解决方案:
onChange={() => setArray(prevState => [...prevState, subOption])}
背景
所以我基于 React 和 Material UI 构建了一个交付服务的前端项目。 我被要求使用一个 Dialog window,它会在单击项目时打开,用户将有机会自定义该项目。 对话框可以在这里看到(非常简单:项目照片、名称、描述和自定义选项):
(抱歉像素化)
问题
我在这个项目中使用了反应钩子,这就是为什么要管理对话框的状态。 虽然简单,但我偶然发现了元素如何 re-rendered/not 重新渲染(预期时)的一些问题:
- 复选框的
"checked"
属性使用Array.some
,查看复选框的唯一ID是否在状态数组中。单击复选框时,复选框未设置为已选中。onChange
道具只是将复选框的值推送到状态数组并设置状态:
const [array, setArray] = React.useState([]);
...
<Checkbox
checked={
array.some(
item => item._id === subOption._id
)
}
onChange={() => setArray(array.push(subOption))}
/>
onChange
动作正常,那么为什么 "checked"
道具不能正常工作?
- 选中一个复选框后,我想在它旁边添加一个小数量字段,这样用户就可以选择他要接收的
subOption
数量。 所以我使用下一个熟练的模式:
{array.some(item => item._id === subOption._id) &&
(
<QuantityField />
)
}
问题是选中复选框后未显示 QuantityField。
如果我退出Dialog再进入,突然看到checked的checkbox被选中了,旁边显示QuantityField
如果我使用您可以在对话框图像左下方看到的通用 QuantityField 更改项目的数量,突然所有选中的复选框都被取消选中 一般的 QuantityField 使用它自己的状态,并且没有连接到任何复选框。
根据我尝试调试奇怪行为后所见,我可以说 Dialog 组件的呈现操作未按预期工作。状态已更新,但不会触发对话树的重新呈现。实际上,这样说是错误的,因为 Dialog 树被重新渲染,但是在重新渲染期间没有重新检查“checked”prop;但是完全卸载并重新安装对话框会使树向右摇晃。
希望得到一个有趣的答案。谢谢。
我会改变您的使用方式 setArray
。参见 Array.prototype.push()
文档:
The
push()
method adds one or more elements to the end of an array and returns the new length of the array.
也不允许在状态上使用 .push()
,因为 永远不应该直接改变状态。
建议的解决方案:
onChange={() => setArray(prevState => [...prevState, subOption])}