Skip to content

Instantly share code, notes, and snippets.

@codervince
Created July 8, 2017 03:13
Show Gist options
  • Save codervince/98c0126203aab125575d66debdc43267 to your computer and use it in GitHub Desktop.
Save codervince/98c0126203aab125575d66debdc43267 to your computer and use it in GitHub Desktop.
Redux and integrating in react - best to outsource the conversion
//actions.js
export const ADD_PRODUCT = 'ADD_PRODUCT';
export const CLEAR_FORM = 'CLEAR_FORM';
....
//NB Reducers MUST be pure functions
/* action creators */
export function addProduct(product){
//must have a type
return {type: ADD_PRODUCT, product: product}
}
export function clearForm (){
return {type: CLEAR_FORM}
}
//reducers.js
import {combineReducers} from 'redux'
import * as ACTIONS from './actions'
// PART 1 THE FORM!!
/*reducers take currentState and action returns new state
when redux is launched first time intial state of form is {} empty form fields => default case
*/
const addProductForm = (state={}, action) => {
switch(action, type){
case ACTIONS.CHANGE_TITLE_FORM:
//copies the curentState to an empty {} plus overwrites with new title
return Object.assign({}, state, {title: action.text});
case ACTIONS.TOGGEL_WATCHED_FORM:
return Object.assign({}, state, {watched: !state.watched});
case ACTIONS.CLEAR_FORM:
return {};
default:
return state;
...
}
// PART 2 THE LIST OF PRODUCTS AS ARRAY
const products = (state= [{title: 'prod1', desctiption: 'ddd'}], action) => {
switch(action, type){
case ACTIONS.ADD_PRODUCT:
return state.concat(action.product);
case ACTIONS.REMOVE_PRODUCT:
//action passes the index of t' prod to be removed
return state.filter( (p,i) -> i !== action.index);
case ACTIONS.TOGGLE_WATCHED:
return state.map( (p,i) => {
if (action.index == i){
return Object.assign({}, p, {watched: !p.watched}(
}
return p;
} etc
//lots of magic here
const productApp = combineReducers({
addProductForm,
prodcts
})
export {productApp};
//CONSUMING IN Index.js
import {productApp} from '/reducers'
const store = createStore(prodictApp);
//logging
const unsubscribe = store.subscribe({} => {
console.log(store.getState())
}
//actions
//simulates filling in the form (once)
store.dispatch(ACTIONS.changeTitle('Redux Chair'))
store.dispatch(ACTIONS.changeDescription('blahhhhhhh'))
//
store.dispatch(ACTIONS.addProduct(store.getState().addProductForm))
//clear form ??
//end listener
unsubscribe()
// Integrating with REACT app.js
//all state information now handled in props
export class App extends React...
consrtuctor(props)
super(props)
}
render() {
return(
<ReduxAddProductForm />
<button onClick={()=> this.props.onProductRemove(0)}> Remove first </button>
//using the ket this way is a bad idea
{this.props.products.map( (p,i) => <ReduxProduct { ...p} key={p.title} nr={i} />}}
)}
//FOLLOWING REQUIRED FOR EVERY COMPONENT!
//ReduxApp.js redux wrapper for app - builds a new React Component extended with Redux
//with new state and event handlers
import {connect} from 'react-redux'
import {App} from '/App'
//call via props.products
const mapStateToProps = (state) => {
return {
products: state.products
}
//dispatch is a function sends to Store
const mapDispatchToProps = (dispatch) => {
return{
onProductRemove: (index) => {
dispatch(ACTIONS.removeProduct(index))
//magic
const ReduxApp= connect(mapStateToProps, mapDispatchToProps)(App);
export {ReduxApp}
//ReduxProducts.js
//here ownProps.nr is the key to access prod in array of prods
const mapStateToProps = (state, ownProps) -> {
title: state.products(ownProps.nr).title,
description: state.products(ownProps.nr).description
}
const mapDispatchToProps = (dispatch) -> {
return {
onToggleWatched: (index) =>
dispatch(ACTIONS.toggleWatched(index))
}
//as be4
const ReduxProduct = connect(mapStateToProps, ,....)(Product)
export ReduxProduct}
//index js
import {Provider} from 'react-redux'
ReactDOM.render(
<Provider store={store}>
<ReduxApp />
</Provider>,
document.....
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment