JavaScript CSS HTML
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src
.babelrc
.eslintrc
.gitignore
.project
LICENSE
LICENSE.md
README.md
_config.yml
bundle.js
index.html
package - Copy.json
package.json
package.json.bak
server.js
webpack.config.dev.js
webpack.config.js
webpack.config.js.bak
webpack.config.js.dev
webpack.config.prod.js

README.md

React-Redux Patterns

By Mark Qian 6/2017 (markqian@hotmail.com)

A. The demo page:

http://coolshare.com/ReactReduxPattern

B. Description:

This package is designed to get you up and running as a comprehensive web application. Another major goal of this package is to illustrate commonly used patterns in a React application. I will first focus on some of the patterns I introduced for my own usage in my projects at work. Then I will list some commonly used ones. The patterns introduced and used by me:

  • Inheritant of html
    Problem: There is no a "nature way" to inherit html from a super class in React.
    And FaceBook even recommends giving up inheritance at all:

    "At Facebook, we use React in thousands of components, and we haven't found any use cases where we would recommend creating component inheritance hierarchies. Props and composition give you all the flexibility you need to customize a component's look and behavior in an explicit and safe way. Remember that components may accept arbitrary props, including primitive values, React elements, or functions. If you want to reuse non-UI functionality between components, we suggest extracting it into a separate JavaScript module. The components may import it and use that function, object, or a class, without extending it."

    This conclusion does not make sense at all. One of the major goals of ES6 is to bring javascript to a higher level: object oriented. Object oriented is a needed pattern in many cases.

    For example, when building series of gadgets for a portal, each gadget has the same html as header where min/max/close boxes are defined. In order to share that common html, we need a class with the header html to by shared by all the gadget classes (concrete gadgets).

    Per the recommendation of the Facebook article above, to use the composition pattern, you need to have a parent class, say Gadget, and a series of child classes like GadgetOne, GadgetTwo, GadgetThree...as the following
	 function Gadget(props) { 
	 	renderHeader() {
			//...
		}
		render() {
			return (
				<div>
					{this.renderHeader()}
					{props.children}
				</div>
			);
		}
	  }
	
	function GadgetOne(props) { return (
			...
	  ); }

and HTML as the following

<Gadget>
  <GadgetOne></GadgetOne>
</Gadget>
<Gadget>
  <GadgetTwo></GadgetTwo>
</Gadget>
<Gadget>
  <GadgetThree></GadgetThree>
</Gadget>

What is the problem with this pattern?
1). There are many redundant codes in html
2). The HTML is not readable at all: you see a lot of "Gadget"s but they do not really mean anything
3). Gadget is a parent/abstract class which has nothing to do with concrete content: you never want to expose it. What if you have multiple parents class that your child gadgets share features from and are you going to end up with something like the following to represent a single gadget?

<Super...SuperGadget>
  ...
  <SuperGadget>
     <GadgetOne></GadgetOne>
  </SuperGadget>
  ...
</Super...SuperGadget>

The problem here is that the relation between Gadget and GadgetOne is not composition but inheritant.

Solution: the inheritant is the key to fix the problem:
The super class:

    export default class Gadget extends React.Component{
    renderHeader() {
        return (
            <div>...</div>
        )
    }
    renderMe() {
        return null;
    }
    render() {
        return (
            <div>
                {this.renderHeader()}
                {this.renderMe()}
            </div>
        )
    }

  }

And the sub class:

import Gadget from '../../../../common/Gadget'
class GadgetOne extends Gadget{
    /**
    * renderMe called in super
    * @return {ReactElement} markup
    */
    renderMe(){

        //...
        return (
            <div>    
		//...
            </div>
        )
    }
}

And HTML:

<GadgetOne/>
<GadgetTwo/>
<GadgetThree/>

Result:

1). No redundant HTML codes
2). Very readable
3). The super class is not expose in HTML



  • Loading components by string class name from a config file
    Problem: In some case, you can not import your custom React classes statically since you don't have them yet.
    One example is a portal where users contribute their own gadgets after you release the portal application. When a new gadget is created by a user, two things are done:

    1). the gadget class is placed in a location that the application can reach.
    2). the location of the gadget class is added to the config file, GadgetConfig.js

    Now how to load it, place it on a page and even inject some dynamic properties to it?

    Solution: here is the step to load and place into a page
    1). import the config file GadgetConfig.js

      import gadgetConfig from '../config/GadgetConfig' 
    


    where GadgetConfig.js contains

      export default const gadgetConfig = {
           "GadgetOne":{"name":"GadgetOne", "path":"../gadgets/GadgetOne", "state":"normal"},
           "GadgetTwo":{"name":"GadgetTwo", "path":"../gadgets/GadgetTwo", "state":"normal"},
           ...
      }
    

    And the GadgetOne.js contains

      export default class GadgetOne extends React.Component{
      	render(){		
      		...
      	}
      }
    

    2). import gadgets dynamically

      for (let k in gadgetConfig) {
      	let g = cm.gadgetConfig[k];
      	let type = require(g.path).default;
      	g.elem = React.createElement(type)
      }
    

    3). Place the GadgetOne into a page and inject a property

      render(){
      	var self = this;
      	...
      	let elems = Object.keys(gadgetConfig).map((k, idx)=>{
      		let gadget = gadgets[k];
      		return (React.cloneElement(gadget.elem, {"key":idx, "myProps":self.props.myProps}))			
      	})
      	return (
      		<div>
      			{elems}
      		</div>
      	) 
         }
    



  • Store Customization
    Problem: Access to the store and store related methods from anywhere is not easy and using many store related methods as-is does not meet our need. For example, we need a dispatch with callback but the as-is dispatch of Redux store does not provide that. We need a global access point to access store and store related methods.

    Solution: Creating a singleton wrapper instance that can be accessed globally. It holds the reference of Redux store and the wrapper of store related methods that satisfies custom need. Here is how to access store anywhere:

      import cs from "./services/CommunicationManager";
    
       cs.getStoreValue("MyReducer", "myVar");
       cs.dispatch({"type":"myType", ...}, myCallback); //custom callback that will be described below
       cs.subscribe("myType", handler);     
    


    See code details at /services/CommunicationService.js and /index.js. The CommunicationService will do a lot more that I will describe below.

  • Dispatch with callback
    Problem: dispatch of Redux store does not allow callback. This is not convenient since you sometimes want to write the handler in the same place of dispatching instead of somewhere else such as in a reducer.

    Solution: one key issue with this is that the callback has to be invoked after every handler including reduces and subscribers is done their jobs. So my approach is to trigger an asynchronous dispatch in a middleware and the asynchronous dispatching is picked up in the next round of event process in a common reducer where the callback is invoked. Here is the way to use it:

          cs.dispatch({"MyType", "data":"mydata"}, action=> {
        	//handle callback here
        })
        

See code details at /services/CommunicationService.js, /components/CommonReducer.js and /components/CommonMiddleware.js.

  • Popup Stack
    Problem: This is not a React specific issue. In your application, in many case to achieve a better user experience, you need to allow users to jump into another point in the component hierarchy. If you simply route (deep linking programmatically or allow user to jump by clicking in some case) to the point you may lost the current stay. The use may totally get lost after they finish the job in current stack level. So you need a state "Stack".
    Another issue you face is that if what you popup is an general component, there could be another "short-cut" link/button pointing to another component. You better not use modal dialog since it may result multi-level modal dialogs, a bad UI behave.

    Solution: I built a component/container, "StackViewContainer". It keeps all level of the stack "modal" so that users have to close all the popups to return when "drilling down" or jumping around. In the running demo, try it out by clicking link "React Patterns" at the top and click at "Popup Pattern" on the left menu which links to an arbitrary component, "Housing Info". This "Housing Info" is "modal" since it hides everything behind but you do not feel it as a dialog but a full page at top of the previous page. Next you can popup more by clicking "Trading Info" at the top-right. You can not go nowhere except clicking at "X" button to return. See code details at /components/StackViewContainer.js. Invocation is easy as

        cs.popup(MyComponent, "MyComponent");
    
  • Wrapper for Redux
    Problem: Redux does a simple pub/sub. All the reducers and subscribers will be invoke for any dispatching (This is really not efficient at all. I am wondering why they don't use type to map the listeners so that not all the listeners are called for each single action dispatching). So you have to place if statement in all the subscribers to only let the corresponding invocation through. Another issue with Redux built-in subscribe is that there is access to action handily and LastAction may not available all the time.

    Solution: I wrote a wrapper, "subscribe" to hide the filtering within the wrapper and inject the action as a parameter. So you can simply subscribe as :

       cs.subscribe("myType", action=>{
       	//handling here
       });
    

    Unsubscribe is also wrap so that you don't need to save the function reference return by subscribe. Just:

        cs.unsubscribe("myType");
    

    See code details at /services/CommunicationService.js;
    Actually, cs.dispatch is another example of wrapper.

  • Dispatch as pub/sub
    Problem: In some case, you want to handle a dispatching in a variety of places/components instead of reducers, or you simply need a pub/sub communication that has nothing to do with saving anything in the store: you only want to let other parties know something happen (with data). But Redux's dispatch only deal with reducers and Redux never upates variables like LastAction when Redux can not find a reducer. So you can not even identify that a dispatching is sent to whom in a subscriber (listener) since the action is never saved anywhere. of action.

    Solution: I add a middleware to collect the action before all the listeners are invoked and then use the collected action in the listeners. In this way, you can handle a dispatched action anywhere out side reducer.

  • Dispatch and subscribe in HTML
    Problem: Don't you feel so annoy about that you always need to write handlers to deal with users activity. In many cases, you really just like to trigger a dispatch with simple data or without data: you simply don't want to write a handler!

    Solution: I introduced two simple components to do communication in HTML:

    • Dispatcher
      Dispatcher allows you to dispatch an action when wrapped element(its child element) is interacted by user like clicking:

      An input dispatch "test1" on "onChange":

      <Dispatcher action={{"type":"test1"}} event="Change"> <input type="text"/></Dispatcher>

      where the value of input will be delivered as the ation.data. Additionally, if you want to set a specific field in the Redux state, you can do it as the following

      An input dispatch "test1" on "onChange" to set to field "test1" for action type "pubsubTest":

      <Dispatcher action={{"type":"test1"}} event="Change" setState="pubsubTest.test1"><input type="text"/></Dispatcher>
      



    • Subscriber
      Subscriber allows you to subscribe an action "type" to receive an action and set action.data as value of its child element (the input):

      	A Input subscribes actionType "test2":<Subscriber ActionType="test2"><input/></Subscriber>
      	where ation.data will be set as the value of input. You can also specify what specific field you like to set to the subscribed element (the input).
      

      To try this demo yourself, just select "React Patterns" at the top link. Than, select "Pubsub Pattern" at the left and have fun! See code details at /common/Dispatcher.js, /common/Subscriber.js, /components/Patterns/RightPane/Pubsub/PubsubComponent.js

  • Pub/sub Pattern
    Problem: the major communication in Redux is that one party dispatches an action and listeners (reducers) receive the action and process it to impact views. But in a complicate application, you sometimes need more handy ways to communicate with other parties. For example, you want to simple publish (dispatch in term of Redux) a topic (action in term of Redux) to subscribers (reducers in term of Redux) in JSX-html instead of defining a handler to dispatch for an UI activity. Or like I discuss in the previous item above, "you only want to let other parties know something happen (with data)" and there is no synchronized impact to the views yet, meaning that the result of the dispatching may not need reducers.

    Solution: I introduced a toolkit, CoolshareReactPubSub.

    You can publish in html like

        render() {
            return (
              <div>
                 <Publisher topic="/left/button"><button>Left</button></Publisher>
                 <Publisher topic="/left/Publish"><a href="#" className="ddd">aaaa</a></Publisher>
                 <Publisher topic="/left/Publish" event="Change" options="{'name':'Mark', 'address':'123 Main Ave San Jose, CA'}">
                   <select>
                     <option value="a">A</option>
                     <option value="b">B</option>
                   </select>
                 </Publisher>
            	   <Publisher topic="/left/Publish">
            	     <MyComponentC/>
            	   </Publisher>
            </div>  
          );
        }
    

And subscribe in html like
    <Subscriber topic="/right/text" field="innerHTML" optionField="text"><p/></Subscriber>



/**** here are some commonly used ones***/

  • React patterns. the following patterns are used in the application

    1). Container/Component. It is used under /components/Patterns: all the components under this directory are written with this pattern.

    See details in /components/Patterns/RightPane/Photo/PhotoComponent.js and /components/Patterns/RightPane/Photo/PhotoContainer.js

    2). State hoisting and Stateless function (pure function): Events are changes in state. Their data needs to be passed to stateful container components parents. Example (in VideoContainer.js and VideoComponent.js):

    The event handler resides in VideoContainer and VideoComponent hoists the data entered by users to
    VideoContainer:
    
    class _VideoContainer extends React.Component {
    		handlePeriod(s) {
     		...		
     	}
     	render() {
     		...
     	    return (
    				< VideoComponent  handlePeriod={this.handlePeriod.bind(this)}}... />
    				...
    			}
    		} 
     export default class VideoComponent extends React.Component{
     	render() {
     	  	...
     		return (
       			<select onChange={(e)=>this.props.handlePeriod(e.target.value)}>
     				...
         		</select>
         	}
        }
     }
    

    and VideoComponent is a stateless "function".
    See details in /components/Patterns/RightPane/Video/VideoComponent.js and /components/Patterns/RightPane/Video/VideoContainer.js

    3). conditional rendering. The is an alternative of routing to show different content/page. Example (in MapContainer.js):

     class _MapContainer extends Component {
     	...
     	render() {
     	    return (
     	    	...
     		    	{(this.props.currentMap==="GoogleMap") && <div><center><div>Some bus stops in SF</div></center><GoogleMapContainer style={{"minHeight":"400px"}}/></div>}
     		    	{(this.props.currentMap==="MapBox") && <MapBoxContainer style={{"minHeight":"400px"}}/>}				    				...
     	    )
     	}
     }
    
     const MapContainer = connect(
     		  store => {
     			    return {
     			    	currentMap: store.MapContainerReducer.currentMap
     			    };
     			  }
     			)(_MapContainer);
     export default MapContainer
    


See details in /components/MainPage/Maps/MapContainer.js

4).Render Callbacks: a function passed as a prop to a component, which allows that component to render something
A common use-case of a render callback was to allow a child to render something using data it did not receive in props. Example (RightPane.js)

    function ChildPane(children) {
       return children(id)
    }
	class _RightPane extends React.Component{
		render(){
			let ChildPane = ({ children  }) => children (this.props.currentPage)
			return (
				 <div>
				 	<ChildPane>
				 		{id=>id==="TodoList"?<TodoList/>:id==="HousingInfo"?<HousingInfo/>:null}
				 	</ChildPane>
				 </div>
			)
		}
	}

The goal of this _RightPane is to display or according this.props.currentPage passed by the parent container (). We first declare ChildPane as a "function" which access another function (children) as parameter and then invoke the function(children passed as parameter) inside ChildPane. ChildPane is used in the render content where Children receives its function parameter (children) as {id=>id==="TodoList"?:id==="HousingInfo"?:null} Then this function is invoke as

    children (this.props.currentPage)

where id above is this.props.currentPage. What is good on this pattern? The benefit is that ChildPane can be used somewhere else with different content instead of "{id=>id==="TodoList"?:id==="HousingInfo"?:null}" with the "this.props.currentPag" built-in like a closure.
See details in /components/MainPage/FormTable/RightPane.js

5).Proxy Component: Wrapping a component with attributes and reuse it.

Example (in TodoList.js)

const Td = props => <td style={{"width":"33%", "border": "1px solid black"}} {...props}/>
	
class _TodoList extends React.Component{
   ...
    render(){
      ...
        return (		                                    
            <tr  key={index} style={{"background":"#FFF"}}>
            <Td>{todo.id}</Td>
            <Td>{todo.text}</Td>
            <Td> <input style={{"marginLeft":"10px"}} 
              ...
   			
    }
}


See details in /components/MainPage/FormTable/TodoList/TodoList.js

The third party software used in the package:

- Basic function/feature of Redux: connect of React-redux, middleware, dispatching actions, subscription and so on. This kit uses a pure Redux pattern in the area communication and view update so no "setState" is used except local state like input content state impact button enable state.
  • Other the 3nd-party lib are used included:

    mapbox-gl, googlemap, react-data-grid, infinite-tree, react-image-gallery, react-tabs, react-youtube

C. Instructions for installation

  1. download the zip file of this package and unzip it to, say c:\ReactReduxPattern
    or simply run the following

    cd c:
    git clone https://github.com/coolshare/ReactReduxPattern.git ReactReduxPattern

  2. install environment

    cd c:\ReactReduxPattern
    npm install

  3. run the application

    npm start

  4. build a production version

    webpack -p

Go Mark's home page http://MarkQian.com to see more.

So my approach is to trigger an asynchronous dispatch in a middleware and the asynchronous dispatching is picked up in the next round of event process in a common reducer where the callback is invoked. Here is the way to use it:

          cs.dispatch({"MyType", "data":"mydata"}, action=> {
        	//handle callback here
        })
        

See code details at /services/CommunicationService.js, /components/CommonReducer.js and /components/CommonMiddleware.js.

  • Popup Stack
    Problem: This is not a React specific issue. In your application, in many case to achieve a better user experience, you need to allow users to jump into another point in the component hierarchy. If you simply route (deep linking programmatically or allow user to jump by clicking in some case) to the point you may lost the current stay. The use may totally get lost after they finish the job in current stack level. So you need a state "Stack".
    Another issue you face is that if what you popup is an general component, there could be another "short-cut" link/button pointing to another component. You better not use modal dialog since it may result multi-level modal dialogs, a bad UI behave.

    Solution: I built a component/container, "StackViewContainer". It keeps all level of the stack "modal" so that users have to close all the popups to return when "drilling down" or jumping around. In the running demo, try it out by clicking link "React Patterns" at the top and click at "Popup Pattern" on the left menu which links to an arbitrary component, "Housing Info". This "Housing Info" is "modal" since it hides everything behind but you do not feel it as a dialog but a full page at top of the previous page. Next you can popup more by clicking "Trading Info" at the top-right. You can not go nowhere except clicking at "X" button to return. See code details at /components/StackViewContainer.js. Invocation is easy as

        cs.popup(MyComponent, "MyComponent");
    
  • Wrapper for Redux
    Problem: Redux does a simple pub/sub. All the reducers and subscribers will be invoke for any dispatching (This is really not efficient at all. I am wondering why they don't use type to map the listeners so that not all the listeners are called for each single action dispatching). So you have to place if statement in all the subscribers to only let the corresponding invocation through. Another issue with Redux built-in subscribe is that there is access to action handily and LastAction may not available all the time.

    Solution: I wrote a wrapper, "subscribe" to hide the filtering within the wrapper and inject the action as a parameter. So you can simply subscribe as :

       cs.subscribe("myType", action=>{
       	//handling here
       });
    

    Unsubscribe is also wrap so that you don't need to save the function reference return by subscribe. Just:

        cs.unsubscribe("myType");
    

    See code details at /services/CommunicationService.js;
    Actually, cs.dispatch is another example of wrapper.

  • Dispatch as pub/sub
    Problem: In some case, you want to handle a dispatching in a variety of places/components instead of reducers, or you simply need a pub/sub communication that has nothing to do with saving anything in the store: you only want to let other parties know something happen (with data). But Redux's dispatch only deal with reducers and Redux never upates variables like LastAction when Redux can not find a reducer. So you can not even identify that a dispatching is sent to whom in a subscriber (listener) since the action is never saved anywhere. of action.

    Solution: I add a middleware to collect the action before all the listeners are invoked and then use the collected action in the listeners. In this way, you can handle a dispatched action anywhere out side reducer.

  • Dispatch and subscribe in HTML
    Problem: Don't you feel so annoy about that you always need to write handlers to deal with users activity. In many cases, you really just like to trigger a dispatch with simple data or without data: you simply don't want to write a handler!

    Solution: I introduced two simple components to do communication in HTML:

    • Dispatcher
      Dispatcher allows you to dispatch an action when wrapped element(its child element) is interacted by user like clicking:

      An input dispatch "test1" on "onChange":

      <Dispatcher action={{"type":"test1"}} event="Change"> <input type="text"/></Dispatcher>

      where the value of input will be delivered as the ation.data. Additionally, if you want to set a specific field in the Redux state, you can do it as the following

      An input dispatch "test1" on "onChange" to set to field "test1" for action type "pubsubTest":

      <Dispatcher action={{"type":"test1"}} event="Change" setState="pubsubTest.test1"><input type="text"/></Dispatcher>
      



    • Subscriber
      Subscriber allows you to subscribe an action "type" to receive an action and set action.data as value of its child element (the input):

      	A Input subscribes actionType "test2":<Subscriber ActionType="test2"><input/></Subscriber>
      	where ation.data will be set as the value of input. You can also specify what specific field you like to set to the subscribed element (the input).
      

      To try this demo yourself, just select "React Patterns" at the top link. Than, select "Pubsub Pattern" at the left and have fun! See code details at /common/Dispatcher.js, /common/Subscriber.js, /components/Patterns/RightPane/Pubsub/PubsubComponent.js

  • Pub/sub Pattern
    Problem: the major communication in Redux is that one party dispatches an action and listeners (reducers) receive the action and process it to impact views. But in a complicate application, you sometimes need more handy ways to communicate with other parties. For example, you want to simple publish (dispatch in term of Redux) a topic (action in term of Redux) to subscribers (reducers in term of Redux) in JSX-html instead of defining a handler to dispatch for an UI activity. Or like I discuss in the previous item above, "you only want to let other parties know something happen (with data)" and there is no synchronized impact to the views yet, meaning that the result of the dispatching may not need reducers.

    Solution: I introduced a toolkit, CoolshareReactPubSub.

    You can publish in html like

        render() {
            return (
              <div>
                 <Publisher topic="/left/button"><button>Left</button></Publisher>
                 <Publisher topic="/left/Publish"><a href="#" className="ddd">aaaa</a></Publisher>
                 <Publisher topic="/left/Publish" event="Change" options="{'name':'Mark', 'address':'123 Main Ave San Jose, CA'}">
                   <select>
                     <option value="a">A</option>
                     <option value="b">B</option>
                   </select>
                 </Publisher>
            	   <Publisher topic="/left/Publish">
            	     <MyComponentC/>
            	   </Publisher>
            </div>  
          );
        }
    

And subscribe in html like
    <Subscriber topic="/right/text" field="innerHTML" optionField="text"><p/></Subscriber>



/**** here are some commonly used ones***/

  • React patterns. the following patterns are used in the application

    1). Container/Component. It is used under /components/Patterns: all the components under this directory are written with this pattern.

    See details in /components/Patterns/RightPane/Photo/PhotoComponent.js and /components/Patterns/RightPane/Photo/PhotoContainer.js

    2). State hoisting and Stateless function (pure function): Events are changes in state. Their data needs to be passed to stateful container components parents. Example (in VideoContainer.js and VideoComponent.js):

    The event handler resides in VideoContainer and VideoComponent hoists the data entered by users to
    VideoContainer:
    
    class _VideoContainer extends React.Component {
    		handlePeriod(s) {
     		...		
     	}
     	render() {
     		...
     	    return (
    				< VideoComponent  handlePeriod={this.handlePeriod.bind(this)}}... />
    				...
    			}
    		} 
     export default class VideoComponent extends React.Component{
     	render() {
     	  	...
     		return (
       			<select onChange={(e)=>this.props.handlePeriod(e.target.value)}>
     				...
         		</select>
         	}
        }
     }
    

    and VideoComponent is a stateless "function".
    See details in /components/Patterns/RightPane/Video/VideoComponent.js and /components/Patterns/RightPane/Video/VideoContainer.js

    3). conditional rendering. The is an alternative of routing to show different content/page. Example (in MapContainer.js):

     class _MapContainer extends Component {
     	...
     	render() {
     	    return (
     	    	...
     		    	{(this.props.currentMap==="GoogleMap") && <div><center><div>Some bus stops in SF</div></center><GoogleMapContainer style={{"minHeight":"400px"}}/></div>}
     		    	{(this.props.currentMap==="MapBox") && <MapBoxContainer style={{"minHeight":"400px"}}/>}				    				...
     	    )
     	}
     }
    
     const MapContainer = connect(
     		  store => {
     			    return {
     			    	currentMap: store.MapContainerReducer.currentMap
     			    };
     			  }
     			)(_MapContainer);
     export default MapContainer
    


See details in /components/MainPage/Maps/MapContainer.js

4).Render Callbacks: a function passed as a prop to a component, which allows that component to render something
A common use-case of a render callback was to allow a child to render something using data it did not receive in props. Example (RightPane.js)

    function ChildPane(children) {
       return children(id)
    }
	class _RightPane extends React.Component{
		render(){
			let ChildPane = ({ children  }) => children (this.props.currentPage)
			return (
				 <div>
				 	<ChildPane>
				 		{id=>id==="TodoList"?<TodoList/>:id==="HousingInfo"?<HousingInfo/>:null}
				 	</ChildPane>
				 </div>
			)
		}
	}

The goal of this _RightPane is to display or according this.props.currentPage passed by the parent container (). We first declare ChildPane as a "function" which access another function (children) as parameter and then invoke the function(children passed as parameter) inside ChildPane. ChildPane is used in the render content where Children receives its function parameter (children) as {id=>id==="TodoList"?:id==="HousingInfo"?:null} Then this function is invoke as

    children (this.props.currentPage)

where id above is this.props.currentPage. What is good on this pattern? The benefit is that ChildPane can be used somewhere else with different content instead of "{id=>id==="TodoList"?:id==="HousingInfo"?:null}" with the "this.props.currentPag" built-in like a closure.
See details in /components/MainPage/FormTable/RightPane.js

5).Proxy Component: Wrapping a component with attributes and reuse it.

Example (in TodoList.js)

const Td = props => <td style={{"width":"33%", "border": "1px solid black"}} {...props}/>
	
class _TodoList extends React.Component{
   ...
    render(){
      ...
        return (		                                    
            <tr  key={index} style={{"background":"#FFF"}}>
            <Td>{todo.id}</Td>
            <Td>{todo.text}</Td>
            <Td> <input style={{"marginLeft":"10px"}} 
              ...
   			
    }
}


See details in /components/MainPage/FormTable/TodoList/TodoList.js

The third party software used in the package:

- Basic function/feature of Redux: connect of React-redux, middleware, dispatching actions, subscription and so on. This kit uses a pure Redux pattern in the area communication and view update so no "setState" is used except local state like input content state impact button enable state.
  • Other the 3nd-party lib are used included:

    mapbox-gl, googlemap, react-data-grid, infinite-tree, react-image-gallery, react-tabs, react-youtube

C. Instructions for installation

  1. download the zip file of this package and unzip it to, say c:\ReactReduxPattern
    or simply run the following

    cd c:
    git clone https://github.com/coolshare/ReactReduxPattern.git ReactReduxPattern

  2. install environment

    cd c:\ReactReduxPattern
    npm install

  3. run the application

    npm start

  4. build a production version

    webpack -p

Go Mark's home page http://MarkQian.com to see more.