Last active
May 3, 2020 23:59
-
-
Save mattboldt/02493bbb6bdaca7ea9bf650fe5cd4436 to your computer and use it in GitHub Desktop.
ES6 Set and Map with React Hooks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import useRefProxy from './useRefProxy' | |
const MyComponent = () => { | |
const [state, setProxy] = useRefProxy(new Set([1, 2, 3, 4])) | |
const [mapState, mapProxy] = useRefProxy( | |
new Map([ | |
[1, { foo: 1 }], | |
[2, { foo: 2 }], | |
]) | |
) | |
return <div> | |
{Array.from(state.values()).join(', ')} | |
<button onClick={() => state.add(5)}>Add to Set</button> | |
</div> | |
} | |
export default MyComponent |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState, useCallback } from 'react' | |
// useForceUpdate Borrowed from mobx-react | |
// https://github.com/mobxjs/mobx-react-lite/blob/7045287a0d1588321c1789e18b410c4567283159/src/utils.ts#L9 | |
function useForceUpdate() { | |
const [, setTick] = useState(0) | |
const update = useCallback(() => { | |
setTick(tick => tick + 1) | |
}, []) | |
return update | |
} | |
export default useForceUpdate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useRef } from 'react' | |
import useForceUpdate from './useForceUpdate' | |
function useRefProxy(initialState) { | |
const set = useRef(initialState) | |
const forceUpdate = useForceUpdate() | |
let proxy = new Proxy(set.current, { | |
get(target, prop, receiver) { | |
let value = Reflect.get(...arguments) | |
if (typeof value === 'function') { | |
forceUpdate() | |
return value.bind(target) | |
} else { | |
return value | |
} | |
}, | |
}) | |
return [set.current, proxy] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment