This file contains hidden or 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
function useIO( fun, condition = [] ) { | |
// Counter of open I/O requests. If it's 0, I/O is completed. | |
// Counter is needed to handle the situation when the next request | |
// is issued before the previous one was completed. | |
const $isReady = useSafeLink( null ); | |
useEffect(()=>{ | |
// function in set instead of value to avoid race conditions with counter increment. | |
$isReady.set( x => ( x || 0 ) + 1 ); |
This file contains hidden or 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
function useThrottle( fun, timeout, changes = [] ){ | |
// Create the mutable local ref to store timer. | |
const timer = useRef( null ); | |
function cancel(){ | |
if( timer.current ){ | |
clearTimeout( timer.current ); | |
timer.current = null; | |
} | |
} |
This file contains hidden or 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
export const DelayedInput = ({ $value, timeout = 1000, ...props }) => { | |
const $inputValue = useBoundLink( $value ) | |
.onChange( | |
useThrottle( | |
x => $value.set( x ), | |
timeout, | |
[ $value.value ] | |
) | |
); | |
This file contains hidden or 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
export const DelayedInput = ({ $value, timeout = 1000, …props }) => { | |
const $inputValue = useBoundLink( $value ); | |
// TODO: How to sync the state back? | |
return <input {…$inputValue.props} {…props}/>; | |
} |
This file contains hidden or 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
function useBoundLink( source ){ | |
// If the source is another Link, extract the value out of it. | |
const value = source instanceof Link ? source.value : source, | |
link = useLink( value ); | |
// If the value changes, execute link.set( value ) after the render. | |
useEffect(() => link.set( value ), [ value ]); | |
return link; | |
} |
This file contains hidden or 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
export const EditUser = ({ $selected, close }) => { | |
const $filter = useLink(''); | |
return ( | |
<> | |
<DelayedInput autoFocus | |
$value={ $filter } | |
placeholder="Start typing..." | |
onBlur={ close } /> | |
This file contains hidden or 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
const userToString = x => x.name + ' <' + x.email + '>'; | |
const PickUser = ({ user }) => ( | |
<div> | |
<input value={userToString(user)}/> | |
</div> | |
) |
This file contains hidden or 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
function useLink( init ){ | |
const [ value, set ] = useState( init ); | |
// It can be a class with useful methods, like this one: | |
// https://github.com/VoliJS/NestedLink/blob/master/valuelink/src/link.ts | |
// But we just use the plain object here to illustrate an idea. | |
return { value, set }; | |
} | |
const PickUser = ({ $selected /* link to some upper component state */ }) => { | |
// Declare the local component's state as a link. |
This file contains hidden or 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 { useLink } from 'valuelink' | |
function Example() { | |
const users = useLink([]); | |
return ( | |
<div> | |
{ users.map( ( user, i ) => ( | |
<div key={i}> |
This file contains hidden or 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
// Minimal working example demonstrating the two-way data binding with React Hook. | |
import { useLink } from 'valuelink' | |
import * as React from 'react' | |
// We don't want to deal with error markup in every input, do we? | |
const Input = ({ link, ...props }) => { | |
return ( | |
<div> | |
<input {...link.props} {...props} /> | |
<span>{ link.error || '' }</span> |