frhooks
v2.2.4-6
Published
Hook React
Downloads
106
Maintainers
Readme
FRHooks React Js
Hook untuk membantu CRUD
or you can try frhooks V2 with a different name
Installation
Install with npm
npm install frhooks
Install with Yarn
yarn add frhooks
required:
- yup
- axios
Hooks
- HookProvider
- apiRoute
- useMutation
- useValidation
- useServerValidation
- useTable
- useFetch
- useDispatch
- useSelector
- useLang
- useHooks
ApiRoute
apiRoute()
.headers({...headers})
- set header
.params({...params})
-set params url
.get(resp => resp, {...config})
-request GET
.destroy(resp => resp, {...config})
-request DELETE
.data({...data})
-set data (method POST | PUT)
.sendJson(method, resp => resp, {...config})
-mengirim data dalam bentuk json ("application/json")
.sendUrlEncode(method, resp => resp, {...config})
-mengirim data dalam bentuk query\ ("application/x-www-form-urlencoded")
.sendFormData(method, resp => resp, {...config})
-mengirim data dalam bentuk query ("multipart/form-data")
.link()
-generate url
Usage/Example
=> Buat url dalam 1 object
=> apiRoutes.js
const apiRoutes = {
project: {
index: "/project",
detail: "/project/:id",
},
...other,
};
export default apiRoutes;
=> Jika Menggunakan Typescript
=> Buat Typescript untuk url
declare namespace FRHooks {
type Route = typeof import(".../apiRoutes").default
type ApiRoute = {
[P in keyof Route]: (
path: keyof Route[P],
arg?: Record<string, string>
) => Api;
};
}
=> Daftar Provider
=> Buat instance dari Axios
import { HookProvider } from 'frhooks';
import axios from 'axios';
import apiRoutes from '../apiRoutes'
const api = axios.create({
baseUrl: 'http://localhost:8000/api'
})
<HookProvider client={api} route={apiRoutes}>
<App/>
</HookProvider>
=> Cara Menggunakan ApiRoute
=> Buat instance dari Axios
=> GET, POST, PUT, DELETE
import React FRHooks from 'react'
import {apiRoute} from 'frhooks'
function App(){
const fetchData = async () => {
data = await apiRoute().project('index').get()
}
const fetchDetail = async (id) => {
data = await apiRoute().project('detail', {id}).get()
}
const postData = async () => {
const data = await apiRoute()
.project('index')
.data({name:'Project A', description: ''})
.sendJson('POST')
}
const destroyData = async () => {
data = await apiRoute().project('detail', {id: 1}).destroy()
}
}
useMutation
Manipulasi Form
Props
| Props | Fungsi | | -------------- | ----------------------------------------------------------------------------- | | defaultValue* | inialisasi nilai awal | | schema | schema validasi attribut menggunakan Yup | | format | memberikan format ketika inputan | | scenario | membagi validasi bedasarkan scenario |
Function you can use
| No | Object | Type | Fungsi | | --- | ------------------------------------ | -------- | ------------------------------------------------------------------------------------------ | | 1 | loading | boolean | Indikator saat request GET | | 2 | processing | boolean | Indiator saat POST, PUT, DESTROY | | 3 | data | T | Data | | 4 | errors | Object | Menampilkan error saat validasi | | 5 | isNewRecord | boolean | Inditator untuk data baru | | 6 | setData(value) | function | Fungsi untuk set data | | 7 | clearData(except:[]) | function | Membersihkan data tambahkan key jika ingin mengeluarkan data yang tidak ingin di bersihkan | | 8 | increment(value) | function | Fungsi untuk manaikan nilai | | 9 | decremet(value) | function | Fungsi untuk menurunkan nilai | | 10 | reformat(cb(value)) | function | Reformat data | | 11 | validate(key, scenario) | boolean | Mendapatkan validasi berdasarkan key | | 12 | fails(scenario) | function | Melakukan validasi manual | | 13 | setError({...error}) | function | Set manual error | | 14 | clearError() | function | Membersihkan Error validasi | | 15 | error(key) | function | Mendapatkan Error berdasarkan key | | 16 | message(key) | string | Mendapatkan pesan error berdasarkan key | | 17 | isValid() | function | Indikator untuk melihat validasi valid | | 18 | merge(values) | function | Menggabungkan data | | 19 | register(key, defaultValue, options) | function | Mendaftarkan Attribute input | | 20 | post | function | Aksi POST | | 21 | put | function | Aksi PUT | | 22 | destroy | function | Aksi DELETE | | 23 | get | function | Aksi GET | | 24 | cancel() | function | Membatalkan request axios | | 25 | addItem(Key, {value}, position) | function | Menambahkan value baru kedalam array | | 26 | setItem(value) | function | Mengubah nilai berdasarkan key | | 27 | getItem(Key, defaultValue) | function | Mendapatkan nilai berdasarkan key | | 28 | removeItem(key, index) | function | Menghapus value dari array berdasarkan index | | 29 | itemValid | boolean | | | 30 | setDispatch() | function | | | 31 | validateItem(key) | boolean | Mendapatkan validasi array berdasarkan index dan field | | 32 | attributes | array | Mendapatkan attribute atau field yand telah daftarkan | | 33 | incrementItem(value) | function | Fungsi untuk manaikan nilai | | 34 | decrementItem(value) | function | Fungsi untuk menurunkan nilai |
Usage/Example
// app.js
import React from 'react'
import {useMutation, useSelector} from 'frhooks'
const App = () => {
const form = useMutation({
defaultValue: {
id: 0,
title: "",
body: "",
items:[]
},
// Optional validasi
schema: (yup: any) =>
yup.object().shape({
title: yup.string().required().label("Title"),
body: yup.string().required().label("Description"),
//Contoh Array
items:yup.array().of(
y.object().shape({
label: y.string().required().label("Label"),
})
)
.required()
}),
// Optional kondisi
isNewRecord: (data) => data.id === 0,
// Optional Scenario
// Memecah field saat validasi berdasarkan scenatio
scenario: {
create: ["title"],
update: ["title", "body"],
step1: ["title"],
step2: ["items"]
},
// Optional Format
// Optional format saat input
format: {
title: (value) => value.trim(),
},
// Optional Tambah Key unik untuk mendaftarkan ke daftar CONTEXT
key: 'key_context'
});
// Contoh mengirim data POST | PUT
const onSubmit = () => {
// Note: ['/example/:id', {id}] gunakan ini jika butuh nilai
form.post('/example', {
// Optional default: post
// Note: form.put(url, options) jika ingin menggunakan PUT
method: "post",
// Optional validasi, default false
// Note: Pastikan schema telah ditambahkan
validation: true,
// Optional scenario, default: false
// Note: Pastikan scenario telah ditambahkan
scenario: "create",
// Optional send post tanpa data, default: false
useEmpty: false,
// Optional send post tanpa data yang di filter
except: [],
// Optional send post hanya data yang di filter
only: [],
onBeforeSend: () => {
console.log('action before send')
},
onSuccess: (data, jhqx) => {
console.log('action on success', data)
},
onError:(e) => {
console.log('error', e)
},
onAlways: () => {
console.log('action on always')
},
options: {
headers: {
//default; application/json
//Note: Ubah bagian ini jika ingin mengirim data menggunakan Form Data, useMutation akan mengubah secara otomatis object => form-data 'content-type': 'multipart/form-data',
//Note: Ubah bagian ini jika ingin mengirim data menggunakan urlencode, useMutation akan mengubah secara otomatis object => query url encode 'content-type': "application/x-www-form-urlencoded",
...(other options axios config)
}
},
...(other options)
})
}
// Contoh Delete
const onDelete = () => {
// Note: ['/example/:id', {id}] gunakan ini jika butuh nilai
form.destroy('/example', {
onSuccess: (data, jhqx) => {
console.log('action on success', data)
},
...(other options)
})
}
// Contoh GET
const get = () => {
// Note: ['/example/:id', {id}] gunakan ini jika butuh nilai
form.get('/example', {
onSuccess: (data, jhqx) => {
console.log('action on success', data)
},
...(other options)
})
}
const change={(e) => {
form.setData({title: e.target.value})
}
//Membuat validasi saat blur
cost blur={() => {
form.validate('title')
}
//Contoh Manual Validasi
const validation = async () => {
//Normal
const invalid = await form.fails();
//Dengan scenario
const invalid = await form.fails('step1')
//Dengan Schema
const invalid = await form.fails((yup) => yup.object().shape({...schema}))
if(invalid) {
console.log(form.errors)
}
}
//Contoh Manual Validasi Array
const validationArray = async () => {
//Normal
const invalid = await form.validateItem('items');
if(invalid) {
console.log(form.errors)
}
}
const addNew = () => {
form.addItem('items', {label: ''}, 'start' | 'end'| number of index)
}
//Note: Hapus Array
const removeItem = (i) => () => {
form.removeItem('items')
//atau
form.removeItem('items', i)
//atau
form.removeItem('items', (v) v.label === 'test')
}
render <div>
{form.loading ? "Memuat Data..." : JSON.stringify(mutation.data)}
<div>
<input value={form.data.title} onChange={change} onBlur={blur}/>
//Atau
<input {...form.register('name',"", {...options})}/>
{form.error('title') ? <span>{form.message('title')}</span> : null}
</div>
<button onClick={validation} >validasi</button>
<button disabled={!form.isValid()} onClick={onSubmit}>
{form.processing ? "loading..." : "simpan"}
</button>
</div>
}
=> Jika Array
const App = () => {
...(form)
return <div>
<ul>
{
form.data.items.map((value, i) => (
<li key={i}>
<input
value={form.getItem('items.0.label', '')}
onChange={(e) => {
form.setItem( {['items.0.label']: e.target.value})
}}
onBlur={() => {
form.validateItem('items.0.label')
}}
/>
{form.error('items.0.label') ? <span>{form.message('items.0.label')}</span> : null}
<button onClick={removeItem(i)}>- Remove Array</button>
</li>
)
)}
</ul>
<button onClick={validationArray} >validasi array</button>
<button onClick={addNew}> + Add New Array</button>
</div>
}
=> Jika Nested Array dan Seterusnya
const App = () => {
...(form)
return <div>
<ul>
{
form.data.items.map((value, i) => value.items2.map((value2, i2) => (
<li key={i}>
<input
value={form.getItem(`items.${i}.items2.${i2}.label`, '')}
onChange={(e) => {
form.setItem( {[`items.${i}.items2.${i2}.label`]: e.target.value})
}}
onBlur={() => {
form.validateItem(`items.${i}.items2.${i2}.label`)
}}
/>
{form.error(`items.${i}.items2.${i2}.label`) ? <span>{form.message(`items.${i}.items2.${i2}.label`)}</span> : null}
<button onClick={() => {
form.removeItem(`items.${i}.items2`, i2)
}}>- Remove Array</button>
</li>
))
)
}
</ul>
<button onClick={() => {
form.validateItem(`items.${i}.items2`)
}} >validasi array</button>
<button onClick={() => {
form.addItem(`items.${i}.items2`, {label: ''})
}}> + Add New Array</button>
</div>
}
useValidation
Menggunakan validasi schema (Yup)
Props
| Props | Fungsi | | -------- | ----------------------------------------------------------------------------- | | schema* | schema validasi attribut menggunakan Yup | | scenario | membagi validasi bedasarkan scenario | | value | Data |
Function you can use
| No | Props | Type | Fungsi | | --- | ---------------------------------------- | -------- | ------------------------------------- | | 1 | errors | object | Hasil validasi | | 2 | scenario | string | Mendapatkan scenario | | 3 | setData({}) | function | set data | | 4 | setError({}) | function | set error manual | | 5 | fails({scenario, value}) | function | Melakukan validasi | | 6 | validate(field, scenario) | boolean | Melakukan validasi per field | | 7 | clearError() | function | Menghapus error | | 8 | error(fields) | boolean | Mendapatkan indikasi error per field | | 9 | message(fields) | boolean | Mendapatkan pesan error per field | | 10 | valid | boolean | Mendapatkan indikasi error | | 11 | validateItem(key, attr, index, scenario) | boolean | Melakukan validasi item array | | 12 | errorItem(key, attr, index) | boolean | Mendapatkan indikasi error item array | | 13 | messageItem(key, attr, index) | string | Mendapatkan pesan error item array |
Usage/Example
// app.js
import React from 'react'
import {useValidation} from 'frhooks'
const App = () => {
const form = useValidation({
// Optional
// value tambahkan value disini untuk validasi bersarkan perubahan data
// form.setData(): jika value ditambahkan maka pada fungsi ini bisa untuk tidak digunakan
value: data,
schema: (yup: any) =>
yup.object().shape({
title: yup.string().required().label("Title"),
body: yup.string().required().label("Description"),
items: y
.array()
.of(
y.object().shape({
text: y.string().required().label("test"),
})
)
.required(),
}),
// Optional Scenario
// Memecah field saat validasi berdasarkan scenatio
scenario: {
create: ["title"],
update: ["body"],
//Experimental jika ingin memvalidasi hanya array saja
//example: form.fails({scenario: "items"})
validationItems: ["items"]
},
});
const validation = async () => {
//Normal
const invalid = await form.fails();
//Dengan scenario
const invalid = await form.fails({scenario: "create"})
//Dengan value
const invalid = await form.fails({value: {...(new value)})
if(invalid) {
console.log(form.errors)
}
}
return "Contoh sama dengan useMutation bukan Array"
}
=> Jika Array
<ul>
{array.map((v, i) => ( <div key={i}>
<input onBlur={() => form.validateItem('items', 'text', i)} />
{form.errorItem('items', 'text', i) ? <span>{form.messageItem('items', 'text', i)}</span> : null}
</div>)}
</ul>
useServerValidation
Menggunakan validasi asyncronus API
Props
| Props | Fungsi | | -------------------------------- | ------------------------------------------------------------- | ------------------------------- | | url | Alamat api yang dituju | | selector:(resp) => resp | Mendapatkan data error dengan normal response < 400 Http Code | | options: {[key]:(param, locale)} | Mengatur object error | | param: {type, path} | Mendapatkan object error | | field | object | Memberi pengaturan invidividual | | callback(err) | Mendpatkan balikan hasil error |
Function you can use
| No | Props | Type | Fungsi | | --- | ----------------------------------------- | -------- | ---------------------------------- | | 1 | processing | boolean | Mendapatkan indikasi proses | | 2 | errors | object | Mendapatkan error | | 3 | serve({url, key, only, method, data, cb}) | function | Melakukan validasi | | 4 | loading | boolen | Mendapatkan indikasi proses | | 5 | validate(key, data, options) | boolean | Melakukan validasi berdasarkan key |
Usage/Example
=> Contoh Error Response Api
//validation.json
error: [
{path: "title", type: "required"},
{path: "phoneNumber", type: 'exist'},
{path: "body", type:"minLength", length: 8}
]
atau
// path dan type diubah menjadi field dan rule
error: [
{field: "title", rule: "required"},
....
]
atau
error:{
code: 5,
name: "is exist"
}
// app.js
import React from 'react'
import {useServerValidation} from 'frhooks'
const App = () => {
const {server, errors} = useServerValidation({
url: "http://localhost/validation",
// Mendapatkan error dari API
selector: (resp) => resp.error,
option: {
//Note: Normal
required: ({path}) => `${path} is required`,
//Note: with locale
required: ({path}, {r, t}) =>r("required", { path: t(path) }, "validation"),
exist: ({path}) => `${path} already exist`,
minLength:({path, length}) => `${path} minimum length is ${length}`,
//Note: jika param diubah
required: ({field}) => `${path} is required`,
},
// Optional
// dapat diubah
param:{
path: "path",// default path,
type: "type",// default type
}
field: {
name: {
url: "exmple.json",
selector: (resp) => {
// Balikan berupa string˝
return resp.data.error.name
}
}
},
// Optional
calback: (err) => {
form.setError(err)
}
});
const validation = async () => {
const valid = await serve({method: "post", ...(other optional options)})
if(!valid){
console.log(errors)
}
}
//Note: Kombinasi dengan useMutation
const onSubmit = () => {
form.post('/example', {
// Optional validasi, default false
validation: true,
serverValidation: {
serve: serve,
method: "post",
},
...(other options)
})
}
return <>{JSON.stringify(errors)}<>
}
useTable
Manipulasi Table
Props
| Props | Fungsi | | ------------------ | --------------------------------------- | | selector* | Mendapatkan data dari respon API | | total* | Mendapatkan jumlah data dari respon API | | disabledOnDidMount | Mematikan aksi saat didmount | | config | Konfigurasi AxiosRequestConfig | | sort | urutan | | pagination | paginasi | | key | Menambahkan data kedaftar CONTEXT |
Function you can use
| No | Object | Type | Fungsi | | --- | -------------------------------------- | ---------- | ---------------------------------------------------------------- | | 1 | loading | boolean | Indikator loading saat GET | | 2 | total | number | Menampilkan total | | 3 | data | T | Data | | 4 | orderBy | string | Menampilkan key urutan | | 5 | order | asd - desc | Menampilkan type urutan | | 6 | query(key, defaultValue) | function | Mendapatkan hasil set query | | 7 | setTotal(value) | function | Set total secara manual | | 8 | setQuery({value}) | function | Set query | | 9 | onOrder(key) | function | Sorting berdasarkan key | | 10 | clear() | function | Membersihkan query | | 11 | clearExcept([]) | function | Membersihkan query dengan parameter | | 12 | clearOnly([]) | function | Membersihkan query dengan parameter | | 13 | remove() | function | Membersihkan Error validasi | | 14 | reload() | function | Memuat ulang | | 15 | remove(key, resetPage) | function | Menghapus query berdasarkan key dan reset page = defaultPage | | 16 | add(value, "start" or "end" or number) | function | Menambahkan data baru kedalam list | | 17 | update(index or (v) => boolean, value) | function | Memperbaharui data list berdasarkan Index | | 18 | destroy(index or (v) => boolean) | function | Menghapus data darri list berdasarlkan Index | | 19 | isEmpty | boolean | Mendapatkan indikasi data kosong | | 20 | has(key) | boolean | Mendapatkan inidikasi dari key query | | 21 | setDispatch() | function | (key: 'list_test') diset untuk mendaftarkan data kedalam context | | 22 | pagination | Object | ... | | 23 | register() | function | ... |
Pagination Function you can use
| Object | Type | Fungsi | | ----------------- | -------- | ------------------------------------- | | page | number | Mendapatkan page | | from | number | Mendapatkan nomor urutan pertama | | to | number | Mendapatkan nomor urutan terakhir | | lastPage | number | Mendapatkan nomor page terakhir | | perPageOptions | number[] | Mendapatkan daftar size page tersedia | | perPage | number | Mendapatkan nilai size page | | setPage(value) | function | Set page manual | | setPerPage(value) | function | Set size page manual | | nextButton() | function | ... | | backButton() | function | ... | | firstButton() | function | ... | | lastButton() | function | ... | | onPerPageChange | function | fungsi untuk set nilai size page | | text | string | Mendapatkan summary data |
Usage/Examples
// list.json
//exmple API response
{
status: 200,
data: [...],
total: 10
}
// app.js
import React from 'react'
import {useTable} from 'frhooks'
const App = () => {
//Note: ["/examples/:path", {path: "test"}] bila ingin menambahkan path
const table = useTable("/examples", {
// Mendapatkan data dari response API
selector: (resp) => resp.data,
// Mendapatkan nilai total dari response API
total: (resp) => resp.total,
// Optional
// Note: Cara merubah params sorting
// Example: localhost/example?order=asc&orderby=id
sort: {
params: {
order: "order",
orderBy: "orderBy",
},
order: "desc", // Note: default order, default: desc
orderBy: "id", // Note: default orderBy, default: id
},
// Optional
// Note: Melakukan custome terhadap pagination
pagination: {
//Example: localhost/example?page=1&perPage=10
params: {
page: "page",
perPage: "perPage",
},
startPage: 1,// default page, default: 1 or 0
perPage: 10,// default perPage, default: 10,
perPageOptions: [5, 10, 15, 25],
// formula mendapatkan nilai from
from: (total, page, size, df) => page - 1 + (df === 0 ? 1 : 0)) * size +
(total === 0 ? 0 : df === 0 ? 1 : df),
// formula mendapatkan nilai to
to: (total, page, size, df) => Math.min(total, (page + (df === 0 ? 1 : 0)) * size),
//Mendapatkan nilai page terakhir
lastPage: (total, size) => Math.max(0, Math.ceil(total / size)), // formula
disableFirst: (total, page, df) => total !== 0 && page === df,
disableLast: (total, page, lp) => total !== 0 && page === lp,
},
// Optional mendaftarkan hasil ke CONTEXT
key: 'key_context',
//tambahkan true jika tidak ingin menjalan saat load page, default: false
disabledOnDidMount: false
})
render <div>
<div>
<input type="text" value={table.query('title', '')} onChange={e => table.setQuery({title: e.target.value})} />
//atau
<input type="text" {...table.register("title", "")} />
{table.pagination.text}
<button {...table.pagination.firstButton()}>prev</button>
<button {...table.pagination.backButton()}>prev</button>
{table.pagination.page}
<button {...table.pagination.nextButton()}>next</button>
<button {...table.pagination.lastButton()}>next</button>
<button onClick={() => table.onOrder("name")}>
{table.order}-{table.orderBy}
</button>
<button onClick={table.clear}>Clear</button>
<button onClick={table.reload}>Reload</button>
</div>
<table>
<thead>
<tr>
<td>No</td>
<td>Title</td>
</tr>
</thead>
<tbody>
{table.loading ? 'loading...' : null}
{table.data.map((v: any, i) => (
<tr key={i}>
<td>{table.data.from + (i+1)}</td>
<td>{v.title}</td>
</tr>
))}
</tbody>
</table>
</div>
}
useFetch
fetching data
Props
| Props | Fungsi | | ------------------ | --------------------------------- | | selector* | Mendapatkan data dari respon API | | defaultValue | Nilai default untuk data | | defaultParams | Nila default untuk query | | disabledOnDidMount | Mematikan aksi saat didmount | | config | Konfigurasi AxiosRequestConfig | | debounceTime | Nilau debounce saat setQuery | | deps | Depedencies | | getData(data) | Mendapatkan Data secara manual | | key | Menambahkan data kedaftar CONTEXT |
Function you can use
| No | Object | Type | Fungsi | | --- | -------------------------------------- | -------- | ------------------------------------------------------------------------- | | 1 | loading | boolean | Indikator loading saat GET | | 2 | total | number | Menampilkan total | | 3 | data | T | Data | | 4 | error | object | error query | | 5 | getQuery(key, defaultValue) | function | Mendapatkan hasil set query | | 6 | setQuery({value}) | function | Set query | | 7 | clear({except, only}) | function | Membersihkan query | | 14 | refresh() | function | Memuat ulang | | 16 | add(value, "start" or "end" or number) | function | Menambahkan data baru kedalam list (jika data dalam bentuk array) | | 17 | update(index or(v) => number, value) | function | Memperbaharui data list berdasarkan Index (jika data dalam bentuk array) | | 18 | destroy(index or (v) => number) | function | Menghapus data dari list berdasarkan Index (jika data dalam bentuk array) | | 19 | isEmpty | boolean | Mendapatkan indikasi data kosong | | 20 | has(key) | boolean | Mendapatkan indikasi dari key query | | 21 | setDispatch() | function | (key: 'list_test') diset untuk mendaftarkan data kedalam context |
Usage/Examples
// list.json
//exmple API response
{
status: 200,
data: [...],
}
// atau
{
status: 200,
data: {...},
}
// app.js
import React from 'react'
import {useFetch} from 'frhooks'
const App = () => {
//Note: ["/examples/:path", {path: "test"}] bila ingin menambahkan path
const project = useFetch("/examples", {
// Mendapatkan data dari response API
selector: (resp) => resp.data,
// Mendapatkan nilai total dari respon API
// Tentukan nilai awal jika array maka [] atau {}
defaultValue: {},
// Optional
// Optional mendaftarkan hasil ke CONTEXT
key: 'key_context',
// Optional
// Tambahkan true jika tidak ingin menjalan saat load page, default: false
disabledOnDidMount: false ,
// Optional
// Jika ingin mendaptkan data secara manual
getData: (value) => {
console.log(value, 'data in here')
}
...(other options)
})
render "Lebih kurang mirip useTable"
}
useDispatch
useSelector
context
Function you can use
| Object | Type | Fungsi | | -------------------- | -------- | ----------------------------------------- | | dispatch(key, value) | function | set data object atau list berdasarkan key | | clearMutation('key') | function | Bersihkan mutasi | | clearList('key') | function | Bersihkan list |
Usage/Examples
=> Jika menggunakan Typescript maka tambahkan ini
//index.d.ts override
declare namespace FRHooks {
type DataContext = {
user: {
name: string;
};
};
}
// app.js
import React from 'react'
import {useDispatch, useSelector} from 'frhooks'
const App = () => {
const {dispatch, clearMutation, clearList} = useDispatch()
// atau
const {dispatch} = useDispatch('key', {
// Optional, default mutation
// Note: Jika array maka ubah menjadi "list"
type: 'mutation',
// Optional hanya untuk bertipe list
total: 0,
defaultValue: {
name: ''
}
})
const result = useSelector(['key'])
// atau modifikasi respon
const result = useSelector(['key'], (data) => data)
React.useEffect(() =>{
dispatch('key', {name: 'test'})
}, [])
render <div>
{JSON.stringify(result)}
</div>
}
useLang
Multi Bahasa
Function you can use
| Object | Type | Fungsi | | --------- | -------- | --------------------------------- | | t() | function | Mendapatkan hasil terjemah bahasa | | r() | function | Memberi nilai berdasarkan param | | setLang() | function | Menentukan bahasa digunakan |
Usage/Examples
// en.json => pastikan nama file benar "${en}".json
// default json
// ini bisa digunakan untuk memodifikasi pesan validasi useMutation
{
"attribute": {
"name": "Name"
},
"message": {
"exampleMessage": "Hello Word",
"exampleReplaceMessage": "Hello :name"
},
"validation": {
"default": ":path is invalid",
"required": ":path is a required field",
"oneOf": ":path must be one of the follwing values: :values",
"notOneOf": ":path must not be one of the following values: \":values\"",
"defined": ":path must be defined",
"stringLength": ":path must be exactly :length characters",
"stringMin": ":path must be at least :min characters",
"stringMax": ":path must be at most :max characters",
"matches": ":path must match the following: \":regex\"",
"email": ":path must be a valid email",
"url": ":path must be a valid URL",
"uuid": ":path must be a valid UUID",
"trim": ":path must be a trimmed string",
"lowercase": ":path must be a lowercase string",
"uppercase": ":path must be a upper case string",
"numberMin": ":path must be greater than or equal to :min",
"numberMax": ":path must be less than or equal to :max",
"lessThan": ":path must be less than :less",
"moreThan": ":path must be greater than :more",
"positive": ":path must be a positive number",
"negative": ":path must be a negative number",
"integer": ":path must be an integer",
"dateMin": ":path field must be later than :min",
"dateMax": ":path field must be at earlier than :max",
"isValue": ":path field must be :value",
"noUnknown": ":path field has unspecified keys: :unknown",
"arrayMin": ":path field must have at least :min items",
"arrayMax": ":path field must have less than or equal to :max items",
"arrayLength": ":path must have :length} items"
}
}
// id.json => pastikan nama file benar "${id}".json
// ini bisa digunakan untuk memodifikasi pesan validasi useMutation
{
"attribute": {
"name": "Nama",
"mandatory": "Wajib"
},
"message": {
"exampleMessage": "Hallo Dunia",
"exampleReplaceMessage": "Hallo :name"
},
"validation": {
"default": ":path tidak valid",
...dll
}
}
//tsconfig
{
"compilerOptions": {
"resolveJsonModule": true,
}
}
// index.d.ts override*
declare namespace FRHooks {
type AttributeKey =
| keyof typeof import("../lang/en.json")["attribute"]
| Array<keyof typeof import("../lang/en.json")["attribute"]>;
type AttributeMessage =
| keyof typeof import("../lang/en.json")["message"]
| Array<keyof typeof import("../lang/en.json")["message"]>;
type Lang = "en" | "id"
}
import { HookProvider } from 'frhooks';
const language = {
lang: 'en',
// folder berisikan file json, en.json, id.json, ...dll
path: './lang/',
fallback: 'en',
// Optional tambah jika ingin memeliki nilai awal
default: {...default},
// Optional
loading: true,
}
// index.js
<HookProvider language={language}>
<App/>
</HookProvider>
// app.js
import React from 'react'
import {useLang} from 'frhooks'
const App = () => {
const {t, r, setLang} = useLang()
React.useEffect(() =>{
setLang('id') // Set Bahasa
}, [])
render <div>
<p>{t('name') || t(['name', 'mandatory'])}</p>
<p>{r('exampleReplaceMessage', {name: 'BUDI'})}</p>
</div>
}