Skip to content

Instantly share code, notes, and snippets.

@katoozi
Created June 21, 2020 08:11
Show Gist options
  • Save katoozi/46eb3446678197f4d59d2738bc54956c to your computer and use it in GitHub Desktop.
Save katoozi/46eb3446678197f4d59d2738bc54956c to your computer and use it in GitHub Desktop.
react native hook and context helpers
/**
createArraySubsets generate array subsets.
@param {Array} array - source array.
@param {number} subsets - number of subsets. default is 2
@returns array with number of given subsets.
@example
createArraySubsets([1,2,3,4,5,6,7,8], 2); // output: [[1,2],[3,4],[5,6],[7,8]]
createArraySubsets([1,2,3,4], 3); // output: [[1,2,3], [4]]
createArraySubsets([1,2,3,4,5,6,7,8], 4); // output: [[1,2,3,4], [5,6,7,8]]
*/
export const createArraySubsets = (array: any[], subsets: number = 2) => {
let start = 0;
let end = subsets;
const tempArray = [];
for (let i = 0; i <= array.length + 1; i++) {
tempArray.push(array.slice(start, end));
if (end > array.length) {
break;
}
start = end;
end = end + subsets;
}
return tempArray.filter(value => value.length !== 0);
};
import React, { useReducer, ElementType } from 'react';
import { ReducerType, BindActions } from './';
/**
createContextData will create Context and Provider.
@param {ReducerType} reducer - reducer function
@param {Object} initialState - reducer initial state object
@param {Object} actions - object of custom functions. example: {onSubmit, onFocuse, ...}
@returns Context and Provider
@example
const {Context, Provider} = createContextData(reducer, initialState, actions);
const {} = useContext(Context);
<Provider>
<App />
</Provider>
*/
export const createContextData = (
reducer: ReducerType,
initialState: Object,
actions: Object = null,
actionWithoutDispatch: Object = null,
) => {
const Context = React.createContext({});
const Provider = ({ children }: { children: ElementType }) => {
const [state, dispatch] = useReducer(reducer, initialState);
const boundActions = BindActions(initialState, dispatch);
const newActions = {};
for (let key in actions) {
newActions[key] = actions[key]({ state, ...boundActions, ...actionWithoutDispatch });
}
return (
<Context.Provider value={{ state, ...boundActions, ...newActions, ...actionWithoutDispatch }}>
{children}
</Context.Provider>
);
};
return { Context, Provider };
};
import { Dispatch } from 'react';
import { Action, ObjectOfBindedActions, BindedAction } from './types';
/**
BindActions will bind actions to dispatch function.
@param {function} dispatch - dispatch function comes from useReducer hook.
@param {string} actionType - action type
@returns function of `BindedAction` type
@example
const setName = ActionCreator(dispatch, 'SET_NAME');
setName('john'); // dispatch SET_NAME action type with john as payload
*/
export const ActionCreator = (dispatch: Dispatch<Action>, actionType: string): BindedAction => {
return (value: Object) => {
dispatch({ type: actionType, payload: value });
};
};
/**
BindActions will bind actions to dispatch function.
@param {Object} initialState - reducer initial state
@param {function} dispatch - dispatch function comes from useReducer hook.
@returns object of `ObjectOfBindedActions` type
@example
const {setLoading, setName} = BindActions({loading: false, name: 'jack'}, dispatch);
setLoading(true); // dispatch setLoading action type with true as payload
setName('john'); // dispatch setName action type with john as payload
*/
export const BindActions = (initialState: Object, dispatch: Dispatch<Action>): ObjectOfBindedActions => {
const Actions: ObjectOfBindedActions = {};
for (let key in initialState) {
let keyString = `set${key.charAt(0).toUpperCase() + key.slice(1)}`;
Actions[keyString] = ActionCreator(dispatch, keyString);
}
return Actions;
};
/**
DynamicReducer is function that dispatch action types dynamicly.
it must be used when you only set values in your reducer.
if you want to change the payload before returning the state then you have to write your own reducer.
@example
const initialState = {loading: false}
const [state, dispatch] = useReducer(DynamicReducer, initialState);
dispatch({type: 'setLoading', payload: true}) // action type must be start with 'set' and capitalize initial state key
*/
export const DynamicReducer = <T>(state: T, action: Action): T => {
const key = action.type.slice(3); // remove 'set' from the action type
// convert the first character to lowercase and append it to rest of the key except for the first character
const stateKey = key.charAt(0).toLowerCase() + key.slice(1);
return { ...state, [stateKey]: action.payload };
};
export * from './context';
export * from './hooks';
export * from './storage';
export * from './types';
export * from './arrays';
import AsyncStorage from '@react-native-community/async-storage';
/**
storeData will save data with key, value format in device storage.
@param {string} key - key that you want set value for it.
@param {string} value - value of the key.
@returns Promise of `Boolean` type
@example
storeData('token', 'some_random_string')
.then(value => {
if(!value){
// error
}
})
*/
export const storeData = async (key: string, value: string) => {
try {
await AsyncStorage.setItem(key, value);
return true;
} catch (e) {
console.log(e);
return false;
}
};
/**
storeData will save data with key, value format in device storage.
@param {string} key - key that you want set value for it.
@returns Promise of `string` type
@example
getData('token')
.then(value => {
if(value !== null){
// token value is ready.
}else{
// token key does not have any value
}
})
*/
export const getData = async (key: string) => {
try {
const value = await AsyncStorage.getItem(key);
if (value !== null) {
return value;
}
return null;
} catch (e) {
console.log(e);
return null;
}
};
import { Dispatch } from 'react';
export interface Action {
type: string;
payload: Object;
}
export type ReducerType = (state: Object, action: Action) => object;
export type BindedAction = (value: Object) => void;
export interface ObjectOfBindedActions {
[x: string]: BindedAction;
}
export type ActionFunction = (dispatch: Dispatch<Action>) => BindedAction;
export interface ObjectOfActions {
[x: string]: ActionFunction;
}
@katoozi
Copy link
Author

katoozi commented Jun 21, 2020

put all files in src/helpers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment