1.0.1 • Published 4 months ago
@genrate/react-redux v1.0.1
GenRate React
GenRate React Redux package aims simplify redux implementation
Install
npm install @genrate/react-redux
Usage
Slice
import { model } from '@genrate/react-redux'
import { PayloadAction } from '@reduxjs/toolkit';
export type UserType = {
email: string,
password: string,
remember: string,
profile: {
name: string;
hobbies: string[];
}
}
export default model<UserType>({
// redux state name
name: 'user',
// initial state value
initialState: {},
// action reducers
reducers: {
set(state, action: PayloadAction<UserType>) {
Object.assign(state, action.payload)
}
}
})
Nested Slice
import { model } from '@genrate/react-redux'
import { PayloadAction } from '@reduxjs/toolkit';
type CommentType = {
message: string,
likes: number
};
const Comment = model<>({ initialState, reducers: {
setComment(state, action: PayloadAction<string>) {
Object.assign(state.message, action.payload)
},
addLike(state) {
Object.assign(state.likes, state.likes + 1)
}
}})
export type Post = {
content: string,
comments: typeof Comment[]
}
const Post = model<Post>({
name: 'post',
initialState: {}
})
// usage in react
const Post = () => {
const content = Post.useContent()
const comments = Post.useComments();
return (
<div>
<span>
{content}
</span>
{comments.map((comment, i) => (
<div key={i}>
<button onClick={() => comment.addLike()} />
<span>
{comment.message}
</span>
</div>
))}
</div>
)
}
Selector
import { select, arg } from '@genrate/react-redux'
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
// const main = (state) => state.user;
// const profile = createSelector([main], state => state.profile)
// const name = createSelector([sample], state => state.name)
// const deep = useSelector(data);
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 '@genrate/react-redux'
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>
)
}