use-selector
v3.0.1
Published
useSelector hook for computing a state from another state
Downloads
11
Maintainers
Readme
useSelector
useSelector hook for computing a state from another state
- Usable without external state management libraries
- Composable utility selectors:
selectKey
selectProjection
- Integration with Recoil
- Native Recoil selectors:
keySelector
projection
- Native Recoil selectors:
- Custom selectors (by implementing the
Selector
interface) - Typescript support!
Instal
npm i --save use-selector
Usage
Read only:
const newState = useSelectorValue(() => {
/* return newState's value here */
}, [dependingState1, dependingState2] /* dependencies */);
Detailed example:
import React, { useState } from 'react';
import { useSelectorValue } from 'use-selector';
function Form() {
const [title, setTitle] = useState('');
const [text, setText] = useState('');
const isFormValid = useSelectorValue(() => title !=== '' && text !== '', [title, text]);
return (
<form>
<input onChange={e => setTitle(e.target.value)} value={title} />
<input onChange={e => setText(e.target.value)} value={text} />
<button disabled={isFormValid} />
</form>
);
}
export default Form;
Advanced usage
Utility Selectors
import React, { useState } from 'react';
import { selectKey, selectProjection } from 'use-selector';
function Profile() {
const [user, setUser] = useState({
info: {
firstName: 'Jane',
lastName: 'Doe'
photo: '/images/jane.png',
title: 'Director',
},
roles: ['ADMIN'],
});
// Read only select, changes NOT reflected in 'user'
const [info, setInfo] = useSelector(selectKey(user, 'info'));
// info = { firstName, lastName, photo, title }
// Read/Write select (by passing setParent = setInfo)
// Changes DO reflect in 'info'
const [name, setName] = useSelector(
selectProjection(info, ['firstname', 'lastName'], setInfo)
)
// name = { firstName, lastName }
// ...
}
Recoil
import { atom } from 'recoil';
import { keySelector, projection } from 'use-selector/recoil';
interface User {
firstName: string,
lastName: string,
email: string | null,
}
interface Session {
user: User,
expires: Date
}
export const sessionState = atom<Session>({
key: 'sessionState'
});
// Read/Write user state in sync with session.user
export const userState = keySelector(sessionState, 'user'); // RecoilState<User>
// Read/Write name state in sync with user
export const nameState = projection(userState, ['firstName', 'lastName']);
// RecoilState<{ firstName: string, lastName: string }>
Custom Selector
function mySelector(parent, setParent) {
return {
get: () => parent + ' mutated',
set: ({ get, set }, newValue) => {
const internalState = get(); // internalState = '${parent} mutated'
set(newValue + ' set'); // internalState = `${newValue} set`
setParent(newValue) // parent = newValue, internalState = `${newValue} set`
},
dependencies: [/* dependencies, optional */]
};
}