From 85ea058eae5337d7209388cf48a63582524a4025 Mon Sep 17 00:00:00 2001 From: MrEfrem Date: Fri, 2 Dec 2016 00:23:13 +0400 Subject: [PATCH] Replace @@ on @ for private actions. For props actionPrefix and reduxActionPrefix now automatically add at the end /. Explicit passed / is necessary between action prefix and action type. Update examples and README.md. --- README.md | 23 +++++++------- .../__snapshots__/createReducer.test.js.snap | 8 ++--- __tests__/createReducer.test.js | 27 +++++++++-------- .../src/components/Modal.js | 4 +-- .../src/containers/page/LeftFrame.js | 7 ++--- .../src/containers/page/RightFrame.js | 7 ++--- .../reused_components/src/components/Modal.js | 27 +++++++++++------ .../src/containers/page/Footer.js | 8 ++--- .../src/containers/page/LeftFrame.js | 30 ++++++++----------- .../src/containers/page/RightFrame.js | 28 ++++++++--------- package.json | 4 +-- src/createBoundedReducer.js | 2 +- src/createReducer.js | 6 ++-- src/reduxSetState.js | 2 +- 14 files changed, 94 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index ec90156..cb456fe 100644 --- a/README.md +++ b/README.md @@ -53,20 +53,23 @@ import { createReducer, getState } from 'redux-fly'; import { MENU_OPEN } from './Menu'; // Action of other component // Type of window closing action (other components might listen in reducers) -export const actionPrivateCloseModal = (actionPrefix) => `${actionPrefix}@@PRIVATE-CLOSE-MODAL`; +export const actionPrivateCloseModal = (actionPrefix) => `${actionPrefix}/@PRIVATE-CLOSE-MODAL`; // To open a modal is public action creator (other components might control the state) -export const openModal = (actionPrefix) => ({ - type: `${actionPrefix}PUBLIC-OPEN-MODAL` -}); +export const createActionOpenModal = (actionPrefix) => ({ type: `${actionPrefix}/PUBLIC-OPEN-MODAL` }); // To close a modal is public action creator (other components might control the state) -export const closeModal = (actionPrefix) => ({ - type: `${actionPrefix}PUBLIC-CLOSE-MODAL` -}); +export const createActionCloseModal = (actionPrefix) => ({ type: `${actionPrefix}/PUBLIC-CLOSE-MODAL` }); // Check is opened modal (other components might check the state) -export const isOpened = (mountPath) => (state) => getState(mountPath)(state).opened; +export const isOpened = (mountPath, allState) => { + const state = getState(mountPath)(allState) + if (state) { + return state.opened + } else { + throw new Error(`Mounting path ${mountPath} isn't valid`) + } +} const Modal = ({ reduxState: { opened }, children, reduxSetState }) => (
@@ -80,8 +83,8 @@ export default createReducer({ opened: false }), listenActions: (props, actionPrefix) => ({ // Listen public actions - [`${actionPrefix}PUBLIC-OPEN-MODAL`]: (state, action) => ({ opened: true }), - [`${actionPrefix}PUBLIC-CLOSE-MODAL`]: (state, action) => ({ opened: false }) + [createActionOpenModal(actionPrefix).type]: (state, action) => ({ opened: true }), + [createActionCloseModal(actionPrefix).type]: (state, action) => ({ opened: false }) [MENU_OPEN]: (state, action) => ({ opened: false }) // Listen action of other component }) })(Modal); diff --git a/__tests__/__snapshots__/createReducer.test.js.snap b/__tests__/__snapshots__/createReducer.test.js.snap index 56bbb69..7e754e7 100644 --- a/__tests__/__snapshots__/createReducer.test.js.snap +++ b/__tests__/__snapshots__/createReducer.test.js.snap @@ -2,7 +2,7 @@ exports[`test Test connectToStore: false 1`] = `
`; exports[`test Test empty (default) actionPrefix 1`] = `
- ui component/ + ui component
`; @@ -135,7 +135,7 @@ exports[`test Test valid init component with provide enhanced redux store 1`] = true - ui component/ + ui component function @@ -158,7 +158,7 @@ exports[`test Test valid init component with provide is pure redux store 1`] = ` true - ui component/ + ui component function @@ -184,7 +184,7 @@ exports[`test Test valid init component without provide redux store 1`] = ` true - ui component/ + ui component function diff --git a/__tests__/createReducer.test.js b/__tests__/createReducer.test.js index 8a0efdd..82d0e8e 100644 --- a/__tests__/createReducer.test.js +++ b/__tests__/createReducer.test.js @@ -272,8 +272,8 @@ test('Test listenActions', () => { class Component extends React.Component { componentDidMount() { - const { dispatch } = this.props - dispatch({ type: `ui component/${UPDATE_TODO}`, text: 'My second todo' }) + const { dispatch, reduxActionPrefix } = this.props + dispatch({ type: `${reduxActionPrefix}/${UPDATE_TODO}`, text: 'My second todo' }) } render() { const { props } = this @@ -284,7 +284,8 @@ test('Test listenActions', () => { } Component.propTypes = { reduxState: PropTypes.object.isRequired, - dispatch: PropTypes.func.isRequired + dispatch: PropTypes.func.isRequired, + reduxActionPrefix: PropTypes.string.isRequired } const ExtendedComponent = compose( createReducer({ @@ -308,8 +309,8 @@ test('Test listenActions is function', () => { class Component extends React.Component { componentDidMount() { - const { dispatch, text } = this.props - dispatch({ type: `ui component/${UPDATE_TODO}`, text }) + const { dispatch, text, reduxActionPrefix } = this.props + dispatch({ type: `${reduxActionPrefix}/${UPDATE_TODO}`, text }) } render() { const { props } = this @@ -321,14 +322,15 @@ test('Test listenActions is function', () => { Component.propTypes = { reduxState: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, - text: PropTypes.string.isRequired + text: PropTypes.string.isRequired, + reduxActionPrefix: PropTypes.string.isRequired } const ExtendedComponent = compose( createReducer({ mountPath: 'ui component', initialState: { text: 'My first todo' }, listenActions: (props, actionPrefix) => - ({ [`${actionPrefix}${UPDATE_TODO}`]: (state, action) => ({ text: action.text, num: props.num }) }) + ({ [`${actionPrefix}/${UPDATE_TODO}`]: (state, action) => ({ text: action.text, num: props.num }) }) }) )(Component) @@ -346,8 +348,8 @@ test('Test listenActions is function in reusable component', () => { class Component extends React.Component { componentDidMount() { - const { dispatch, text } = this.props - dispatch({ type: `ui component/${UPDATE_TODO}`, text }) + const { dispatch, text, reduxActionPrefix } = this.props + dispatch({ type: `${reduxActionPrefix}/${UPDATE_TODO}`, text }) } render() { const { props } = this @@ -359,14 +361,15 @@ test('Test listenActions is function in reusable component', () => { Component.propTypes = { reduxState: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, - text: PropTypes.string.isRequired + text: PropTypes.string.isRequired, + reduxActionPrefix: PropTypes.string.isRequired } const ExtendedComponent = compose( createReducer({ mountPath: 'main', initialState: { text: 'My first todo' }, listenActions: (props, actionPrefix) => - ({ [`${actionPrefix}${UPDATE_TODO}`]: (state, action) => ({ text: action.text, num: props.num }) }) + ({ [`${actionPrefix}/${UPDATE_TODO}`]: (state, action) => ({ text: action.text, num: props.num }) }) }) )(Component) @@ -472,7 +475,7 @@ test('Test empty (default) actionPrefix', () => { if (actionType === 'reset') { expect(action.type).toBe(`ui component/${RESET_STATE}`) } else { - expect(action.type).toBe('ui component/@@UPDATE-TODO') + expect(action.type).toBe('ui component/@UPDATE-TODO') } } const store = createStore(() => {}, compose(applyMiddleware(middleware), enhanceStore)) diff --git a/examples/nested_reused_components/src/components/Modal.js b/examples/nested_reused_components/src/components/Modal.js index d601419..21be2ca 100644 --- a/examples/nested_reused_components/src/components/Modal.js +++ b/examples/nested_reused_components/src/components/Modal.js @@ -4,7 +4,7 @@ import { createReducer } from 'redux-fly' import Button from './Button' // Public actions (other components might control) -export const PUBLIC_OPEN_MODAL = 'PUBLIC-OPEN-MODAL' +export const createActionOpenModal = (actionPrefix: string) => ({ type: `${actionPrefix}/PUBLIC-OPEN-MODAL` }) const style = { container: (opened) => ({ @@ -49,7 +49,7 @@ export default createReducer({ opened: false }, listenActions: (props, actionPrefix) => ({ // Listen public actions - [`${actionPrefix}${PUBLIC_OPEN_MODAL}`]: () => ({ // Listen action to open a modal + [createActionOpenModal(actionPrefix).type]: () => ({ // Listen action to open a modal opened: true }) }) diff --git a/examples/nested_reused_components/src/containers/page/LeftFrame.js b/examples/nested_reused_components/src/containers/page/LeftFrame.js index 6ca37b3..5faa25c 100644 --- a/examples/nested_reused_components/src/containers/page/LeftFrame.js +++ b/examples/nested_reused_components/src/containers/page/LeftFrame.js @@ -1,18 +1,17 @@ //@flow import React from 'react' -import Modal, { PUBLIC_OPEN_MODAL } from '../../components/Modal' +import Modal, { createActionOpenModal } from '../../components/Modal' import { connect } from 'react-redux' const modalMountPath = 'leftFrame modal' -const modalActionPrefix = `${modalMountPath}/` const LeftFrame = ({ dispatch }: { dispatch: Function }) => (

Left frame

- - +
) diff --git a/examples/nested_reused_components/src/containers/page/RightFrame.js b/examples/nested_reused_components/src/containers/page/RightFrame.js index 474a7ff..d3b0db9 100644 --- a/examples/nested_reused_components/src/containers/page/RightFrame.js +++ b/examples/nested_reused_components/src/containers/page/RightFrame.js @@ -1,18 +1,17 @@ //@flow import React from 'react' -import Modal, { PUBLIC_OPEN_MODAL } from '../../components/Modal' +import Modal, { createActionOpenModal } from '../../components/Modal' import { connect } from 'react-redux' const modalMountPath = 'rightFrame modal' -const modalActionPrefix = `${modalMountPath}/` const RightFrame = ({ dispatch }: { dispatch: Function }) => (

Right frame

- - +
) diff --git a/examples/reused_components/src/components/Modal.js b/examples/reused_components/src/components/Modal.js index e48c675..afacdf1 100644 --- a/examples/reused_components/src/components/Modal.js +++ b/examples/reused_components/src/components/Modal.js @@ -2,15 +2,24 @@ import React from 'react' import { createReducer, getState } from 'redux-fly' -// Public actions (other components might control) -export const PUBLIC_OPEN_MODAL = 'PUBLIC-OPEN-MODAL' -export const PUBLIC_CLOSE_MODAL = 'PUBLIC-CLOSE-MODAL' +// Type of window closing action (other components might listen in reducers) +export const actionPrivateCloseModal = (actionPrefix: string) => `${actionPrefix}/@PRIVATE-CLOSE-MODAL` -// Private action (other components might listen) -export const PRIVATE_CLOSE_MODAL = '@@PRIVATE-CLOSE-MODAL' +// To open a modal is public action creator (other components might control the state) +export const createActionOpenModal = (actionPrefix: string) => ({ type: `${actionPrefix}/PUBLIC-OPEN-MODAL` }) + +// To close a modal is public action creator (other components might control the state) +export const createActionCloseModal = (actionPrefix: string) => ({ type: `${actionPrefix}/PUBLIC-CLOSE-MODAL` }) // Check is opened modal (other components might check) -export const isOpened = (mountPath: string, state: Object) => getState(mountPath)(state).opened +export const isOpened = (mountPath: string, allState: Object) => { + const state = getState(mountPath)(allState) + if (state) { + return state.opened + } else { + throw new Error(`Mounting path ${mountPath} isn't valid`) + } +} const style = { container: (opened) => ({ @@ -45,7 +54,7 @@ const Modal = ({ reduxState: { opened }, children = 'Hi, I is modal', reduxSetSt
reduxSetState('PRIVATE-CLOSE-MODAL', { opened: false })}>× {children} -
@@ -56,10 +65,10 @@ export default createReducer({ opened: false }, listenActions: (props, actionPrefix) => ({ // Listen public actions - [`${actionPrefix}${PUBLIC_OPEN_MODAL}`]: () => ({ // Listen action to open a modal + [createActionOpenModal(actionPrefix).type]: () => ({ // Listen action to open a modal opened: true }), - [`${actionPrefix}${PUBLIC_CLOSE_MODAL}`]: () => ({ // Listen action to close a modal + [createActionCloseModal(actionPrefix).type]: () => ({ // Listen action to close a modal opened: false }) }) diff --git a/examples/reused_components/src/containers/page/Footer.js b/examples/reused_components/src/containers/page/Footer.js index ad70f2f..d53c32f 100644 --- a/examples/reused_components/src/containers/page/Footer.js +++ b/examples/reused_components/src/containers/page/Footer.js @@ -21,11 +21,11 @@ export default createReducer({ logs: [] }, listenActions: { - [leftOpenModal().type]: saveLog('Left frame open modal (public action)'), - [leftCloseModal().type]: saveLog('Left frame close modal (public action)'), + [leftOpenModal.type]: saveLog('Left frame open modal (public action)'), + [leftCloseModal.type]: saveLog('Left frame close modal (public action)'), [leftPrivateCloseModal]: saveLog('Left frame close modal (private action)'), - [rightOpenModal().type]: saveLog('Right frame open modal (public action)'), - [rightCloseModal().type]: saveLog('Right frame close modal (public action)'), + [rightOpenModal.type]: saveLog('Right frame open modal (public action)'), + [rightCloseModal.type]: saveLog('Right frame close modal (public action)'), [rightPrivateCloseModal]: saveLog('Right frame close modal (private action)'), } })(Footer) diff --git a/examples/reused_components/src/containers/page/LeftFrame.js b/examples/reused_components/src/containers/page/LeftFrame.js index 6d5c900..3d2b9d5 100644 --- a/examples/reused_components/src/containers/page/LeftFrame.js +++ b/examples/reused_components/src/containers/page/LeftFrame.js @@ -1,50 +1,46 @@ //@flow import React, { PropTypes } from 'react' -import Modal, { PUBLIC_OPEN_MODAL, PUBLIC_CLOSE_MODAL, PRIVATE_CLOSE_MODAL, isOpened } from '../../components/Modal' +import Modal, { createActionOpenModal, createActionCloseModal, actionPrivateCloseModal, isOpened } from '../../components/Modal' import { connect } from 'react-redux' import { openModal as rightOpenModal, closeModal as rightCloseModal, isOpenedModal as rightIsOpenedModal } from './RightFrame' import { compose, getContext } from 'recompose' const modalMountPath = 'leftFrame modal' -const modalActionPrefix = `${modalMountPath}/` // Check is opened modal export const isOpenedModal = (state: Object) => isOpened(modalMountPath, state) -// To open a modal is action creator -export const openModal = () => ({ - type: `${modalActionPrefix}${PUBLIC_OPEN_MODAL}` -}) -// To close a modal is action creator -export const closeModal = () => ({ - type: `${modalActionPrefix}${PUBLIC_CLOSE_MODAL}` -}) +// To open a modal is action +export const openModal = createActionOpenModal(modalMountPath) -// Listen private action -export const privateCloseModal = `${modalActionPrefix}${PRIVATE_CLOSE_MODAL}` +// To close a modal is action +export const closeModal = createActionCloseModal(modalMountPath) + +// Listen private action close modal +export const privateCloseModal = actionPrivateCloseModal(modalMountPath) // To toggle opened a right frame modal const toggleRight = (dispatch, store) => { if (rightIsOpenedModal(store.getState())) { - dispatch(rightCloseModal()) + dispatch(rightCloseModal) } else { - dispatch(rightOpenModal()) + dispatch(rightOpenModal) } } const LeftFrame = ({ dispatch, store }: { dispatch: Function, store: Object }) => (

Left frame

-

- diff --git a/examples/reused_components/src/containers/page/RightFrame.js b/examples/reused_components/src/containers/page/RightFrame.js index d51a1fb..6169a4e 100644 --- a/examples/reused_components/src/containers/page/RightFrame.js +++ b/examples/reused_components/src/containers/page/RightFrame.js @@ -1,51 +1,47 @@ //@flow import React, { PropTypes } from 'react' -import Modal, { PUBLIC_OPEN_MODAL, PUBLIC_CLOSE_MODAL, PRIVATE_CLOSE_MODAL, isOpened } from '../../components/Modal' +import Modal, { createActionOpenModal, createActionCloseModal, actionPrivateCloseModal, isOpened } from '../../components/Modal' import { connect } from 'react-redux' import { openModal as leftOpenModal, closeModal as leftCloseModal, isOpenedModal as leftIsOpenedModal } from './LeftFrame' import { compose, getContext } from 'recompose' const modalMountPath = 'rightFrame modal' -const modalActionPrefix = 'right-frame/' +const modalActionPrefix = 'right-frame' // Check is opened modal export const isOpenedModal = (state: Object) => isOpened(modalMountPath, state) -// To open a modal is action creator -export const openModal = () => ({ - type: `${modalActionPrefix}${PUBLIC_OPEN_MODAL}` -}) +// To open a modal is action +export const openModal = createActionOpenModal(modalActionPrefix) -// To close a modal is action creator -export const closeModal = () => ({ - type: `${modalActionPrefix}${PUBLIC_CLOSE_MODAL}` -}) +// To close a modal is action +export const closeModal = createActionCloseModal(modalActionPrefix) // Listen private action -export const privateCloseModal = `${modalActionPrefix}${PRIVATE_CLOSE_MODAL}` +export const privateCloseModal = actionPrivateCloseModal(modalActionPrefix) // To toggle opened a right frame modal const toggleLeft = (dispatch, store) => { if (leftIsOpenedModal(store.getState())) { - dispatch(leftCloseModal()) + dispatch(leftCloseModal) } else { - dispatch(leftOpenModal()) + dispatch(leftOpenModal) } } const RightFrame = ({ dispatch, store }: { dispatch: Function, store: Object }) => (

Right frame

-

- diff --git a/package.json b/package.json index 238f853..ac7ff67 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "redux-fly", - "version": "0.1.2", - "description": "Rapid React + Redux development", + "version": "0.2.0", + "description": "The rapid development of scaling applications on React and Redux", "browser": "dist/redux-fly.js", "main": "lib/index.js", "module": "es/index.js", diff --git a/src/createBoundedReducer.js b/src/createBoundedReducer.js index 35f0865..a307e17 100644 --- a/src/createBoundedReducer.js +++ b/src/createBoundedReducer.js @@ -14,7 +14,7 @@ import { RESET_STATE, MOUNT_PATH, NEW_STATE } from './consts' */ export default (mountPath: string, initialState: Object, listenActions: Object, actionPrefix: string) => (state: Object = initialState, action: Object) => { - const resetState = `${actionPrefix}${RESET_STATE}` + const resetState = `${actionPrefix}/${RESET_STATE}` if ((typeof action[MOUNT_PATH] !== 'undefined' && action[MOUNT_PATH] === mountPath && typeof action[NEW_STATE] !== 'undefined') || action.type in listenActions ) { diff --git a/src/createReducer.js b/src/createReducer.js index ffc302b..ec5dc3a 100644 --- a/src/createReducer.js +++ b/src/createReducer.js @@ -165,9 +165,9 @@ export default ({ // Default value for action prefix contain mounting path if (!this.actionPrefix) { if (typeof propMountPath !== 'undefined') { - this.actionPrefix = `${normalizeMountPath(propMountPath)}/` + this.actionPrefix = `${normalizeMountPath(propMountPath)}` } else { - this.actionPrefix = `${normalizeMountPath(mountPath)}/` + this.actionPrefix = `${normalizeMountPath(mountPath)}` } } @@ -226,7 +226,7 @@ export default ({ this.reduxSetState = reduxSetState(_mountPath, store.dispatch, store.getState, this.actionPrefix) // Action creator RESET redux state this.reduxResetState = () => store.dispatch({ - type: `${this.actionPrefix}${RESET_STATE}`, + type: `${this.actionPrefix}/${RESET_STATE}`, [MOUNT_PATH]: _mountPath, [NEW_STATE]: (_initialState: Object), }) diff --git a/src/reduxSetState.js b/src/reduxSetState.js index 395463b..c0936d4 100644 --- a/src/reduxSetState.js +++ b/src/reduxSetState.js @@ -36,7 +36,7 @@ export default (mountPath: string, dispatch: Function, getState: Function, actio // Else dispatch calculated state dispatch({ - type: `${actionPrefix}@@${actionType}`, + type: `${actionPrefix}/@${actionType}`, [NEW_STATE]: _newState, [MOUNT_PATH]: mountPath })