Last active
April 20, 2018 17:40
-
-
Save Yengas/c9ad601466d28fc23226 to your computer and use it in GitHub Desktop.
Simple React-Redux example with async/sync actions using redux-actions, redux-thunk and react-redux bindings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import {createStore, bindActionCreators, applyMiddleware} from 'redux' | |
| import {createAction, handleActions} from 'redux-actions' | |
| import thunkMiddleware from 'redux-thunk' | |
| import React from 'react' | |
| import ReactDOM from 'react-dom' | |
| import {Provider, connect} from 'react-redux' | |
| // React classes and rendering... | |
| class MessageApp extends React.Component{ | |
| render(){ | |
| return ( | |
| <div> | |
| <h1>Messaging App</h1> | |
| <h2>Send Message</h2> | |
| {/* Take reference of the input dom object and put it into this.input */} | |
| <input type="text" ref={(node) => { this.input = node; }} placeholder="Your Message..." /> | |
| {/* When clicked on this button call props.actions.addMessage function with the inputs value and trust it will add the message. */} | |
| <input type="button" | |
| onClick={() => { this.props.actions.addMessage({author: 'Yengas', message: this.input.value}); }} | |
| value="Send" /> | |
| <h2>Messages</h2> | |
| <h3>Topic: {this.props.topic}</h3> | |
| {/* Map the messages in the props to li elements.*/} | |
| <ul> | |
| {this.props.messages.map((message) => { | |
| return ( | |
| <li key={message.author + message.message}>{message.author}: {message.message}</li> | |
| ); | |
| })} | |
| </ul> | |
| </div> | |
| ); | |
| } | |
| } | |
| // Initial state to fire up the UI and create the reducer with. | |
| const initialState = { | |
| messages: [ | |
| { author: 'Yengas', message: 'Hello, World!' } | |
| ], | |
| topic: 'I love rock and roll!' | |
| }; | |
| // Create the actions we will use in our app | |
| const setTitle = createAction('SET_TITLE'); | |
| const addMessage = createAction('ADD_MESSAGE'); | |
| const editMessage = createAction('EDIT_MESSAGE'); | |
| const removeMessage = createAction('REMOVE_MESSAGE'); | |
| const clearMessages = createAction('CLEAR_MESSAGES'); | |
| // Return a function that takes store's dispatch as argument and dispatches other actions. This way we can create async actions. Requires redux-thunk | |
| const sendMessage = (message) => (dispatch) => { | |
| window.setTimeout(() => { dispatch(addMessage(message)); }, 2000); | |
| }; | |
| // Create a reducer that handles some actions | |
| const reducer = handleActions({ | |
| 'SET_TITLE' (state, action) { | |
| return {...state, topic: action.payload}; | |
| }, | |
| 'ADD_MESSAGE' (state, action) { | |
| const {author, message} = action.payload | |
| return {...state, messages: [...state.messages, { author, message }]}; | |
| } | |
| }, initialState); | |
| // Create a redux store and apply the thunk middleware so we can make async actions that can use dispatch | |
| const store = createStore(reducer, applyMiddleware(thunkMiddleware)); | |
| // Mapping redux store state to react element props | |
| const mapStateToProps = (state) => { | |
| //Same as: return {messages: state.messages, topic: state.topic}; | |
| return state; | |
| }; | |
| // Mapping our actions to react element props after we bind them with store's dispatch function | |
| const mapDispatchToProps = (dispatch) => { | |
| return { | |
| actions: bindActionCreators({setTitle, addMessage, sendMessage, editMessage, removeMessage, clearMessages}, dispatch) | |
| }; | |
| }; | |
| // Create a new react element with the above configs | |
| const ConnectMessageApp = connect(mapStateToProps, mapDispatchToProps)(MessageApp); | |
| // Wait for the document to load so we can access the dom element we are going to render to | |
| window.addEventListener("DOMContentLoaded", () => { | |
| // Use the react-redux provided `Provider` to pass store instances to children of Provider. This way the connect function will work properly. | |
| // then render into #root element | |
| ReactDOM.render(<Provider store={store}> | |
| <ConnectMessageApp /> | |
| </Provider>, document.querySelector("#root")); | |
| // Try out dispatching an action to store. This will change the rendered react elements props and make it re-render. | |
| // This re-rendering process is react-redux optimized. | |
| store.dispatch(setTitle("I love anime too!")); | |
| // Async message sending test. | |
| store.dispatch(sendMessage({author:"Yengas", message:"WOW async message!"})); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice example.