@kollorg/molestias-non v4.6.99
GenRate Redux
GenRate Redux package aims simplify redux implementation
Install
npm install @kollorg/molestias-non
Usage
Slice
import { model, as } from '@kollorg/molestias-non'
import { PayloadAction } from '@reduxjs/toolkit';
const state = {
email: as<string>('test@sample.com'), // required
password: as<string>(), // optional
remember: as<boolean | undefined>(false), // optional with default
profile: {
name: as<string>();
hobbies: as<string[]>();
}
}
export type UserState = typeof state;
export default model(
'user', // slice name
state, // slice state
{
// reducers
set(state, action: PayloadAction<UserState>) {
Object.assign(state, action.payload)
}
}, {
// selectors
isPlayingBasketball: (state) => state.profile?.hobbies?.indexOf('basketball') > -1
}
)
Nested Slice
import { model, as, asModelList, StateType } from '@kollorg/molestias-non'
import { PayloadAction } from '@reduxjs/toolkit';
const commentState = {
message: as<string>(),
likes: as<number>(0)
};
const Comment = model('comment', commentState, {
set(state, action: PayloadAction<string>) {
state.message = action.payload
},
addLike(state) {
state.likes += 1
}
})
const postState = {
content: as<string>(),
newCommentStatus: as<string>('idle'),
comments: asModelList(Comment, []) // as type model array
}
type PostState = StateType<typeof postState>
const Post = model('post', postState,
// ReducerCreators
({ reducer, asyncThunk }) => ({
set: reducer<string>(state, { payload }) {
state.content = payload
},
addComment: asyncThunk( // async reducer
async (comment: string) => {
const response = await apiAddComment(comment)
return response.data
},
{
pending: state => {
state.newCommentStatus = "loading"
},
fulfilled: (state, action) => {
state.newCommentStatus = "idle"
state.message = action.payload
},
rejected: state => {
state.newCommentStatus = "failed"
},
},
)
// selectors
}), {
commentsWithLikes: (state) => state.comments.filter(c => c.likes > 0)
}
)
// usage in react
const Post = () => {
const content = Post.useContent()
const comments = Post.useCommentsWithLikes();
const addComment = Post.useAddComment();
return (
<div>
<span>
{content}
</span>
{comments.map(
(comment, i) => (
<div key={i}>
<button onClick={() => comment.addLike()} /> // inherit model actions
<span>
{comment.message}
</span>
</div>
)
)}
</div>
)
}
Selector
import { select, arg } from '@kollorg/molestias-non'
import User from './models/user'
const getProfileName = select([User.profile], (profile) => profile.name);
// selector with arguments
const hasHobby = select(
[User.profile.hobbies],
[arg<string>(1)],
(hobbies, hobby) => hobbies.find(h => h == hobby);
)
// using on react
const name = useSelector(getProfile); //
const name = getProfile.useSelect();
// with arguments
const isPlayingBadminton = useSelector(state => hasHobby(state, 'badminton'));
const isPlayingBasketball = hasHobby.useSelect('basketball');
Slice in react
import User from './models/user'
const Component = () => {
// auto memoized selector
const user = User.useAll(); // eq = useSelector(state => state.user)
// deep selector
// sampe as
// cachedUser = (state) => state.user;
// cachedProfile = createSelector([main], state => state.profile)
// cachedName = createSelector([profile], state => state.name)
// deep = useSelector(name);
const name = User.profile.useName()
// get action with dispatch
const setUser = User.useSet();
return (
<div>
<span> {user && user.email} </span>
<button onClick={() => setUser({ email: 'test@gmail' })} />
<div>
)
}
RTX Query
import { fetch } from '@kollorg/molestias-non'
const { api, get, post } = fetch('posts')
type User = {
id: number,
name: string
}
const UserApi = api({
getOne: get<User, number>((id) => `users/${id}`),
update: post<User, Partial<User>>((update) => ({ url: `users/${id}`, body: update }))
// test: get<User, number>(
// (id) => `users/${id}`, {
// transform: (res) => res.data,
// tags: (_post, _err, id) => [{ type: 'Posts', id: }] // provideTags
// }
// )
})
function Component () => {
const [user, { isFetching }] = UserApi.useGetQuery(1);
const [updateUser, { isLoading }] = UserApi.useUpdateMutation())
return (
<div>
{isFetching ? 'Loading' : user.name }
<button onClick={() => updateUser({ name: 'test' })} />
</div>
)
}
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago