Recoil version is 0.0.13.
Run below code and click "Float64Array" or "Uint8Array" button, then error will be thrown.
https://codesandbox.io/s/condescending-gagarin-8r9gf?file=/src/App.js
const testState = atom({
key: "test",
default: null
});
const Inner = () => {
const [test, setTest] = useRecoilState(testState);
return (
<div>
value: {test && test.hoge.length}
<button
onClick={() => {
setTest({ hoge: ["1111", "22222"] });
}}
>
Array
</button>
<button
onClick={() => {
setTest({
hoge: new Float64Array(new ArrayBuffer(64), 32, 2)
});
}}
>
Float64Array
</button>
<button
onClick={() => {
setTest({
hoge: new Uint8Array(1)
});
}}
>
Uint8Array
</button>
</div>
);
};
export default function App() {
return (
<RecoilRoot>
<div className="App">
<Inner />
</div>
</RecoilRoot>
);
}
error detail is below.
Cannot freeze array buffer views with elements
deepFreezeValue
https://8r9gf.csb.app/node_modules/recoil/es/recoil.js:1675:10
Object.mySet [as set]
https://8r9gf.csb.app/node_modules/recoil/es/recoil.js:2143:9
setNodeValue
https://8r9gf.csb.app/node_modules/recoil/es/recoil.js:375:15
eval
https://8r9gf.csb.app/node_modules/recoil/es/recoil.js:580:30
Object.replaceState
https://8r9gf.csb.app/node_modules/recoil/es/recoil.js:1070:18
eval
https://8r9gf.csb.app/node_modules/recoil/es/recoil.js:578:60
Object.trace
https://8r9gf.csb.app/node_modules/recoil/es/recoil.js:515:10
setRecoilValue
https://8r9gf.csb.app/node_modules/recoil/es/recoil.js:578:18
eval
https://8r9gf.csb.app/node_modules/recoil/es/recoil.js:1360:5
onClick
...
This error seems to relate to below line.
https://github.com/facebookexperimental/Recoil/blob/e018c3abfb68f559bf493ba244079fa73f89e79b/src/util/Recoil_deepFreezeValue.js#L65
Object.freeze cannot freeze ArrayBufferView(such as Float64Array, Uint8Array...etc).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
So, It may be necessary to add a process to check if it is ArrayBufferView value to the shouldNotBeFrozen function
Is there a better way to handle this?
I guess it's fair to add a check for ArrayBufferView types in shouldNotBeFrozen. It is not possible to guarantee data preserving in the buffer, and I believe developers (assumably) know that they are using this technology at their own risk?
cc @drarmstr
Fixed in master. Not yet released, but you can use the build in the nightly branch.
Most helpful comment
Fixed in master. Not yet released, but you can use the build in the
nightlybranch.