This is a package with use-create-signal. Hook that improves default useState to make it into Signal apprach
npm install use-create-signalImplements createSignal from Solid-JS for React-JS
Lightweight package that fixes most useState problems:
- value is locked in scope
- setState doens't return value
- parallel updated only possible with predicates
Just like you use useState
But value is a getter function
``tsx
type DefaultValueType
type UseCreateSignalType
defaultValue?: DefaultValueType
) => [() => T, (setter: SetStateAction
`
`jsx
const Component = () => {
const [getter, setter] = useCreateSignal('');
return setter(e.target.value)} />;
};
`
Or if you also need value, it's gonna be here
`jsx
const Component = () => {
const [getter, setter, value] = useCreateSignal('');
return setter(e.target.value)} />;
};
`
- useCallback / useEffect and others don't require to put value in depsuseEffect
- consecutive have updated valuesuseEffect
- parallel have actual updated values
- multiple child components will have actual updated values
- memo-components: getter is always the same function. so if you pass getter-function directly - also pass it's result
`jsx
const Component = () => {
const [getter, setter] = useCreateSignal(() => 1); // or just useCreateSignal(1). it's the same as useState
const handleIncrement = useCallback(() => {
const newValue = setter(getter() + 1);
console.log('no deps required. newValue: ', newValue);
}, []);
const handleWowIncrement = useCallback(() => {
const newValue = setter(old => old + 1);
console.log('WOW. it returned value from predicate. Much wow', newValue);
}, []);
// these effects have values updated in between
useEffect(() => {
const value = getter();
console.log(setter(value + 1)); // return 2
}, []);
useEffect(() => {
const value = getter();
console.log(setter(value + 1)); // return 3
}, []);
useEffect(() => {
const value = getter();
// parallel effects didn't get updated values
// this does
if (value > 2) return;
console.log(setter(value + 1)); // won't execute
}, []);
return
`jsx
const InputWithValidation = ({ value, hasError, onValidation }) => {
useEffect(() => {
const isNotValid = value > 100; onValidation(isNotValid);
}, [value]);
return 'Something';
};
const MultipleInputs = ({ onErrors }) => {
const [getFormErrors, setFormErrors] = useCreateSignal({});
const formErrors = getFormErrors();
const handleOnErrors = newErrors => {
setFormErrors(newErrors);
onErrors?.(newErrors);
};
return (
value={190}
hasError={formErrors.first}
onValidation={isValid =>
handleOnErrors({ ...getFormErrors(), first: isValid })
}
// this would fail, as only last input would be validated
// onValidation={isValid => handleOnErrors({ ...formErrors, first: isValid })}
/>
value={310}
hasError={formErrors.second}
onValidation={isValid =>
handleOnErrors({ ...getFormErrors(), second: isValid })
}
/>
value={90}
hasError={formErrors.third}
onValidation={isValid =>
handleOnErrors({ ...getFormErrors(), third: isValid })
}
/>
value={20}
hasError={formErrors.fourth}
onValidation={isValid =>
handleOnErrors({ ...getFormErrors(), fourth: isValid })
}
/>
value={290}
hasError={formErrors.fifth}
onValidation={isValid =>
handleOnErrors({ ...getFormErrors(), fifth: isValid })
}
/>
);
};
``