项目作者: pavelivanov

项目描述 :
Redux reducers without constants and dispatching!
高级语言: TypeScript
项目地址: git://github.com/pavelivanov/redaction.git
创建时间: 2016-07-21T20:53:12Z
项目社区:https://github.com/pavelivanov/redaction

开源协议:MIT License

下载




Redux reducers without constants and dispatching!

Redaction is wrapper for reducers. The main purpose is to refuse from using constants and dispatch method in code.

Npm Version
Month Downloads
Npm Licence

Installation

To install the stable version:

  1. npm install --save redaction

Overview

In large projects usage of the standard Redux approach becomes a headache because of of the huge amount of constants and pushing the dispatch across the entire application logic. Redaction comes to help us solve these problems.

Note: Redaction is just wrapper over Redux, so it’s not reinventing the wheel, it’s sweet sugar :)

BEWARE: If you use / or planning to use SSR in your project DON’T USE Redaction! Currently there are some approaches inside which prevents from doing with SSR in easy way.. If you still want to use it and get problems with SSR fill free to contact me grammka@gmail.com.

Redux approach

constants/todos.js
  1. const ADD_TODO = 'ADD_TODO'
  2. export {
  3. ADD_TODO
  4. }
reducers/todos.js
  1. import { ADD_TODO } from 'constants/todos'
  2. const initialState = {
  3. todos: []
  4. }
  5. export default (state = initialState, action) => {
  6. switch (action.type) {
  7. case ADD_TODO:
  8. return {
  9. ...state,
  10. todos: [
  11. ...state.todos,
  12. action.payload
  13. ]
  14. }
  15. default:
  16. return state
  17. }
  18. }
actions/todos.js
  1. import { ADD_TODO } from 'constants/todos'
  2. export const addTodo = (text) => (dispatch) => {
  3. dispatch({
  4. type: ADD_TODO,
  5. payload: text
  6. })
  7. }
App.js
  1. import { connect } from 'react-redux'
  2. import { addTODO } from 'actions/todos'
  3. const App = ({ todos, addTodo }) => (
  4. <div>
  5. {
  6. todos.map((text, index) => (
  7. <div key={index}>{text}</div>
  8. ))
  9. }
  10. <button onClick={() => addTodo('new todo name')}>Add</button>
  11. </div>
  12. )
  13. const mapStateToProps = (state) => ({
  14. todos: state.todos,
  15. })
  16. const mapDispatchToProps = (dispatch) => ({
  17. addTodo: (text) => {
  18. dispatch(addTodo(text))
  19. }
  20. })
  21. export default connect(mapStateToProps, mapDispatchToProps)(App)


Same with Redaction

reducers/todos.js
  1. export const initialState = {
  2. todos: []
  3. }
  4. export const addTodo = (state, payload) => ({
  5. ...state,
  6. todos: [
  7. ...state.todos,
  8. payload
  9. ]
  10. })
actions/todos.js
  1. import { reducers } from 'core/reducers' // read docs to understand what core folder means
  2. export const addTodo = (text) => {
  3. reducers.todos.addTodo(text)
  4. }

App.js

  1. import actions from 'actions'
  2. import { connect } from 'redaction'
  3. const App = ({ todos }) => (
  4. <div>
  5. {
  6. todos.map((text, index) => (
  7. <div key={index}>{text}</div>
  8. ))
  9. }
  10. <button onClick={() => actions.addTodo('new todo name')}>Add</button>
  11. </div>
  12. )
  13. export default connect({
  14. todos: 'todos'
  15. })(App)
That’s it! Nifty :) No constants! No dispatch!


Usage

actions/users.js
  1. import reducers from 'core/reducers'
  2. export const getAll = () => {
  3. fetch({
  4. endpoint: '/api/users',
  5. method: 'GET'
  6. })
  7. .then((result) => {
  8. reducers.users.put(result)
  9. })
  10. }
reducers/users.js
  1. export const initialState = {
  2. list: [],
  3. }
  4. export const put = (state, payload) => ({
  5. ...state,
  6. list: [
  7. ...state.list,
  8. payload,
  9. ]
  10. })
core/store.js
  1. import { createStore, combineReducers } from 'redaction'
  2. import { reducer as form } from 'redux-form'
  3. import reducers from 'reducers'
  4. const initialState = {}
  5. const store = createStore({
  6. reducers: {
  7. ...combineReducers(reducers),
  8. form,
  9. },
  10. initialState,
  11. })
  12. export default store
core/reducers.js
  1. import { wrapReducers } from 'redaction'
  2. import reducers from 'reducers'
  3. export default wrapReducers(reducers)
components/Posts.js
  1. import React from 'react'
  2. import { users } from 'actions'
  3. export default class Posts extends React.Component {
  4. componentWillMount() {
  5. users.getAll()
  6. }
  7. }


Features

Connect

There is sugar to connect state to components nifty:

  1. import React, { Component } from 'react'
  2. import { connect } from 'redaction'
  3. // option 1
  4. @connect(state => ({
  5. todos: state.todos.list,
  6. }))
  7. // option 2
  8. @connect({
  9. todos: 'todos.list',
  10. })
  11. // option 3
  12. @connect({
  13. todos: (state) => state.todos.list,
  14. })
  15. export default class TodosList extends Component {}


Examples

Repo examples


Tests

To run tests:

  1. npm test


TODO

  • Support React hooks