如何用MobX观察Cookie?实现Cookie变更触发autorun的方案
嘿,这个需求我太懂了——之前用布尔值翻转触发autorun确实有点啰嗦,完全可以把Cookie包装成可观察对象,让它的变更自动触发你的反应逻辑!下面给你两种实用的方案,看哪种更贴合你的技术栈:
方案一:结合MobX直接包装成可观察Cookie对象
如果你正在用MobX,最直接的方式是把Cookie的读写逻辑包装成一个observable对象,让MobX自动追踪它的变化。这样你不用手动维护触发信号,autorun/reaction会自动响应Cookie的变更。
监听整个Cookie字符串的变化
这种方式适合关注整体Cookie变更的场景:
import { observable, autorun } from 'mobx'; // 创建可观察的Cookie包装器 const observableCookie = observable({ get value() { // 读取时返回当前的Cookie字符串 return document.cookie; }, set value(newCookieStr) { // 设置时更新真实的Cookie document.cookie = newCookieStr; } }); // 现在autorun会自动追踪Cookie的变化 autorun(() => { console.log('Cookie已更新:', observableCookie.value); // 这里写你需要自动执行的逻辑 }); // 测试:设置Cookie会立即触发autorun observableCookie.value = 'username=willstone; path=/';
监听单个Cookie键的变化
如果需要精准监听某个Cookie键的变化,可以把Cookie解析成对象来包装:
import { observable, action, autorun } from 'mobx'; const observableCookies = observable({ get cookies() { // 把Cookie字符串解析成键值对对象 return document.cookie.split('; ').reduce((acc, cookie) => { const [key, value] = cookie.split('='); if (key) acc[key] = decodeURIComponent(value); return acc; }, {}); }, // 封装设置单个Cookie的action setCookie: action((key, value, options = {}) => { let cookieStr = `${encodeURIComponent(key)}=${encodeURIComponent(value)}`; if (options.path) cookieStr += `; path=${options.path}`; if (options.expires) cookieStr += `; expires=${options.expires.toUTCString()}`; if (options.maxAge) cookieStr += `; max-age=${options.maxAge}`; // 其他Cookie选项(如domain、secure等)可按需添加 document.cookie = cookieStr; }) }); // 监听特定Cookie键的变化 autorun(() => { console.log('username Cookie的值:', observableCookies.cookies.username); }); // 设置单个Cookie,触发autorun observableCookies.setCookie('username', 'willstone', { path: '/' });
方案二:原生JS监听Cookie变更(无MobX依赖)
如果你的项目没用到MobX,也可以通过重写document.cookie的setter来触发自定义事件,然后监听这个事件执行逻辑:
// 保存原生的Cookie setter const originalCookieSetter = Object.getOwnPropertyDescriptor(document, 'cookie').set; // 重写setter,添加自定义事件触发逻辑 Object.defineProperty(document, 'cookie', { set: function(newCookieStr) { // 先执行原生的Cookie设置逻辑 originalCookieSetter.call(this, newCookieStr); // 触发自定义的cookiechange事件 window.dispatchEvent(new CustomEvent('cookiechange', { detail: { changedCookie: newCookieStr, allCookies: document.cookie } })); } }); // 监听自定义事件,执行你的逻辑 window.addEventListener('cookiechange', (e) => { console.log('Cookie被修改:', e.detail.changedCookie); console.log('当前所有Cookie:', e.detail.allCookies); // 这里写你需要自动执行的代码 }); // 测试 document.cookie = 'test=123; path=/';
注意事项
- 重写
document.cookie的方式在现代浏览器都能正常工作,但如果需要兼容极旧浏览器(如IE10及以下),可能需要额外处理。 - 如果用MobX的方案,记得把包装器放在全局store或者组件的状态管理中,方便复用。
内容的提问来源于stack exchange,提问作者Will Stone
相关产品推荐
相关产品推荐

