Mantine Select组件数据更新后选项不刷新怎么办?
在用Mantine的Select组件时遇到了奇怪的问题,当通过API动态更新选项数据后,界面显示的选项列表完全没变:
我按照文档这样写的代码:
import { Select } from '@mantine/core';
function DynamicSelect({ initialData }) {
const [data, setData] = useState(initialData);
useEffect(() => {
// 模拟异步更新数据
setTimeout(() => {
setData(['new', 'options']);
}, 2000);
}, []);
return (
<Select
label="选择"
data={data}
placeholder="请选择"
/>
);
}
两秒后控制台显示data状态确实变成了[‘new’, ‘options’],但Select组件里的选项还是初始值。尝试过加key属性和用defaultValue都没用,难道是Mantine的Select有特殊更新机制?
useSelect的hook,它默认只在第一次渲染时读取dataprops,之后不会再响应更新——除非你用的是带searchable或者multiple的版本(它们用了不同的内部逻辑,反而能更新),但单纯data更新是不行的。官方文档里其实提过一句(虽然藏得挺深),要让
data动态更新,必须配合key或者用useEffect强制重载。最简单的办法是:给Select加一个随data变化的key,比如直接用data的字符串化结果当key,虽然有点土但管用。或者更稳妥点,用
useRef加forceUpdate那种方式也行,但对新手来说上面这个最直接。另外提醒一句,别用
defaultValue配data,这俩是互斥的——defaultValue只在第一次生效,后面data变了它也不管,这点官方文档里写在“controlled vs uncontrolled”那节,但确实容易踩坑。你现在的写法setData(['new', 'options'])看起来没问题,但如果initialData本身就是个空数组或者简单数组,React可能认为这是相同引用,导致组件没触发重渲染。
解决方案很简单:确保每次更新都返回一个新数组引用。你可以这样改:
更稳妥的方式是在API返回后直接展开:
另外检查一下你的initialData是不是也在变,如果是的话记得在useEffect依赖项里加上它。别搞什么key大法,治标不治本。
这问题和浏览器兼容没关系,纯属React状态更新的常见陷阱。记住一点:数组和对象要换内容,就得换引用。