@genrate/react-redux
v1.0.3
Published
Simplified react redux/toolkit implementation
Downloads
6
Maintainers
Readme
GenRate React Redux
GenRate React Redux package is combination of Genrate React and Redux approach
Advantages
- Separate Logic & Design
- Preserve UI Design
- Components Flexible Reusability
- Simplify re-render handling
- Encourage micro components
Installation
npm install @genrate/react-redux
Usage
Component
import { useData } from '@genrate/react-redux';
import PostAPI from '@api/posts';
import User from '@models/user';
// Output
const Avatar = ({ fullname }) => (
<h5>{fullname}</h5>
);
const Post = ({ content = 'My first post' }) => (
<li>
{content}
</li>
);
const PostFallback = ({ title = 'Loading ...' }) => (
<p>{title}</p>
);
// Input
const AddPost = () => (
<div>
<input name="newPost" />
<button>Add Post</button>
</div>
);
// Layout
const Header = () => (
<div>
<Avatar />
<button>Logout</button>
</div>
);
const Footer = () => (<div>© 2024</div>);
const PostsLayout = () => (
<div>
<Header />
<AddPost />
<ul>
<Post />
</ul>
<Footer />
</div>
);
// Functionality
const PostLists = () => {
const { view, each, query, model, pass, attach } = useData({
// local state
local: {
newPost: ''
},
// redux selectors
selectors: {
// manual selector
userId: () => (state) => state.user.id
// using @generate/redux
fullname: () => User.fullname,
},
// react hooks
hooks: {
// rtx query application
posts: ({ userId }) => PostAPI.useGetByUserQuery(userId),
// set specific data key for hooks that returns array
'addPost|addStatus': () => PostAPI.useAddPostMutation(),
},
});
// redux actions
const logout = User.useLogout();
// render only once
return view(PostsLayout, {
// query inside a component
Header: query({
// pass data to component as props
Avatar: pass('fullname'),
// apply action event
button: () => () => ({
onClick: () => logout()
})
}),
AddPost: query({
// bind input model default to `name` props
input: model(),
button:
// subscribe to specific data
({ newPost, addPost, addStatus }) =>
// set props to button component
() => ({
onClick: () => addPost({ content: newPost }),
disabled: addStatus.isLoading
})
}),
// iterate component base on posts data
Post: each(
({ posts }) =>
() => posts?.data?.map(
// pass content props to each post component
p => ({ content: p.content })
) ?? [
// attach fallback component when posts is loading or empty
attach(PostFallback, {
title: posts?.isLoading ? 'Loading posts...' : 'No posts found' }
)
]
),
});
};