CSSStyleSheet对象无法克隆,存入Redux Store遇空对象问题
解决CSSStyleSheet无法克隆存入Redux Store的问题
你遇到的问题本质是:CSSStyleSheet是浏览器提供的宿主对象,它的核心属性几乎都是不可枚举的。展开运算符、Object.assign、JSON.stringify这些方法只会读取对象的可枚举属性,所以才会拿到空对象。
要把样式数据存入Redux Store,不能直接存CSSStyleSheet实例,得先把它转换成可序列化的普通对象,步骤如下:
1. 提取CSSStyleSheet的可序列化数据
先把样式表的关键信息(比如规则文本、媒体查询、启用状态)提取出来:
function sheetToSerializable(sheet) { // 把cssRules转换成文本数组 const rules = Array.from(sheet.cssRules).map(rule => rule.cssText); return { disabled: sheet.disabled, media: sheet.media.mediaText, cssRules: rules, ownerNodeType: sheet.ownerNode.nodeName.toLowerCase() }; } // 用法 const serializedSheet = sheetToSerializable(sheet); console.log(serializedSheet); // 这是普通对象,可以正常存入Redux
2. 从序列化数据还原CSSStyleSheet
从Redux Store取出数据后,再还原成可生效的样式:
function serializableToSheet(data) { const styleEl = document.createElement(data.ownerNodeType === 'style' ? 'style' : 'link'); if (data.ownerNodeType === 'style') { // 拼接所有规则文本 styleEl.innerHTML = data.cssRules.join('\n'); } else { // 如果是link标签的样式表,可根据需求扩展href等属性 styleEl.rel = 'stylesheet'; styleEl.media = data.media; } styleEl.disabled = data.disabled; document.head.appendChild(styleEl); return styleEl.sheet; } // 用法 const restoredSheet = serializableToSheet(serializedSheet);
为什么不能直接存CSSStyleSheet?
Redux要求Store里的状态必须是可序列化的普通JS对象/数组/基本类型,宿主对象(比如DOM元素、CSSStyleSheet)不仅不可序列化,还和浏览器环境强绑定,存进Store会打破Redux的纯函数原则,还可能导致内存泄漏。
内容的提问来源于stack exchange,提问作者arnaudpf
相关产品推荐
相关产品推荐

