diff --git a/.gitignore b/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/LICENSE b/LICENSE index 0ce6454..f635d8d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Vadim +Copyright (c) 2019 Vadim Kudriavtcev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 6a60076..d4cfa42 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,138 @@ -# Redux-helper +# Redux Array Helper -Effortless operations with Reducers +Effortless operations with Reducers. + +Motivation - make operations with redux store as simple as possible and keep data immutable. + +If you currently doing update like this. + +```javascript +export default function example(state = initialState, action) { + + switch (action.type) { + + case UPDATE: + return { + ...state, + list: state.sections.map(item => { + if (item._id !== action.payload._id) { + return item + } + return { + ...item, + ...action.payload + } + }) + } + + default: + return state; + + } + +} +``` + +You can do this shorter: + +```javascript + +export default function example(state = initialState, action) { + + switch (action.type) { + + case UPDATE: + return { + ...state, + list: ReduxArrayHelper.update(state.list, action.payload) + } + + default: + return state; + + } + +} +``` + +And many other short operations of CRUD. More examples below. + +### Installation + +Copy ReduxHelper.js to your project. For example to src/utils/ folder. + +### Importing + +```javascript +import { ReduxArrayHelper } from '../utils/ReduxHelper' +``` + +### Methods + +| Method | First Arguments | Second Arguments | Third Arguments | Description | +| ------ | ------ | ------ | ------ | ------ | +| append | list | payload | - | Insert to the end of the list | +| prepend | list | payload | - | Insert to the end of the list | +| insert | list | payload | index | Insert to position of the list | +| update | list | payload | (optional) comparator | Update item of list by id in the payload | +| updateByIndex | list | payload | index (int) | Update item of list by payload | +| delete | list | payload | (optional) comparator | Delete item from the list by id in the payload | +| deleteById | list | payload (id) | (optional) comparator | Delete item from the list using payload | +| deleteByIndex | list | index (int) | - | Delete item from the list using payload | +| find | list | payload | (optional) comparator | Return the item from the list by id in the payload | +| findById | list | payload (id) | (optional) comparator | Return the item from the list by payload| +| findIndexById | list | payload (id) | (optional) comparator | Return index of item by payload | + +if you are using MongoDB, pass the third argument COMPORATOR as string key '_id'. + +```javascript +ReduxArrayHelper.update(state.list, action.payload, '_id') +``` + +### Payload from action. + +```javascript +{ + id: 1, + title: 'Redux the best!', + size: 300, +} +``` + +### Reducer + +```javascript +import { + CREATE_BOOK, + UPDATE_BOOK, + DELETE_BOOK, +} from '../var/Examples' + +import { ReduxArrayHelper } from '../utils/ReduxHelper' + +const initialState = { + list: [ + { id: 1, title: 'Redux awesome!'} + ], +} + +export default function examples(state = initialState, action) { + + switch (action.type) { + + case CREATE_BOOK: + return { ...state, list: ReduxArrayHelper.append(state.list, action.payload) } + + case UPDATE_BOOK: + return { ...state, list: ReduxArrayHelper.update(state.list, action.payload) } + + case DELETE_BOOK: + return { ...state, list: ReduxArrayHelper.delete(state.list, action.payload) } + + default: + return state; + + } + +} +``` \ No newline at end of file diff --git a/ReduxHelper.js b/ReduxHelper.js new file mode 100644 index 0000000..d9622a0 --- /dev/null +++ b/ReduxHelper.js @@ -0,0 +1,102 @@ +export const ReduxArrayHelper = { + + append: (list, payload) => { + if(!list || !Array.isArray(list)) return [payload] + let newList = Array.from(list) + newList.push(payload) + return newList + }, + + prepend: (list, payload) => { + if(!list || !Array.isArray(list)) return [payload] + let newList = Array.from(list) + newList.unshift(payload) + return newList + }, + + insert: (list, payload, index) => { + if(!list || !Array.isArray(list)) return [payload] + let newList = Array.from(list) + newList.splice(index, 0, payload) + return newList + }, + + update: (list, payload, comparator = 'id') => { + if(!list || !Array.isArray(list) || !payload) return list + return Array.from(list).map(item => { + if (item[comparator] !== payload[comparator]) { + return item + } + return { + ...item, + ...payload + } + }) + }, + + updateByIndex: (list, payload, index) => { + if(!list || !Array.isArray(list) || !payload) return list + return Array.from(list).map((item, i) => { + if (index !== i) { + return item + } + return { + ...item, + ...payload + } + }) + }, + + delete: (list, payload, comparator = 'id') => { + if(!list || !Array.isArray(list) || !payload) return list + return list.filter((data) => data[comparator] !== payload[comparator]) + }, + + deleteById: (list, payload, comparator = 'id') => { + if(!list || !Array.isArray(list) || !payload) return list + return list.filter((data) => data[comparator] !== payload) + }, + + deleteByIndex: (list, payload) => { + if(!list || !Array.isArray(list) || (!payload && payload !== 0)) return list + return list.splice(payload, 1) + }, + + find: (list, payload, compare = 'id') => { + if(!list || !Array.isArray(list)) return false + return list.find((data) => data[compare] === payload.id) + }, + + findById: (list, payload, compare = 'id') => { + if(!list || !Array.isArray(list)) return false + return list.find((data) => data[compare] === payload) + }, + + findIndexById: (list, payload, compare = 'id') => { + if(!list || !Array.isArray(list)) return false + return list.findIndex((data) => data[compare] === payload) + }, + + toObjectByKey: (list, key = 'id') => { + if(!list || !Array.isArray(list)) return list + let cache = {} + list.forEach(data => { + cache[data[key]] = data + }) + return cache + }, + + groupedToObjectByKey: (list, key = 'id') => { + if(!list || !Array.isArray(list)) return list + let cache = {} + list.forEach(data => { + if(!cache[data[key]]) { + cache[data[key]] = [data] + } else { + cache[data[key]].push(data) + } + }) + return cache + } + +} \ No newline at end of file