1.0.1 • Published 4 months ago

@genrate/react-redux v1.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

GenRate React

npm package Build Status Downloads Issues codecov Commitizen Friendly Semantic Release

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>
  )
}