Skip to content

Instantly share code, notes, and snippets.

@kittolau
Created August 11, 2017 13:25
Show Gist options
  • Save kittolau/93620f3f50200d95d6a082b9ef04fbdb to your computer and use it in GitHub Desktop.
Save kittolau/93620f3f50200d95d6a082b9ef04fbdb to your computer and use it in GitHub Desktop.
react
import React from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import { createStore,applyMiddleware } from 'redux';
import { Provider, connect} from 'react-redux';
import createSagaMiddleware from 'redux-saga'
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
//////////////////////////////
// redux-saga-middleware.js
function someDelayCall(){
return new Promise( (res,rej) => {
setTimeout( () => res(), 2000)
})
}
function* fetchUser(action) {
try {
const user = yield call(someDelayCall, action.id);
yield put({type: "USER_FETCH_SUCCEEDED", user: user});
} catch (e) {
yield put({type: "USER_FETCH_FAILED", message: e.message});
}
}
/*
Starts fetchUser on each dispatched `USER_FETCH_REQUESTED` action.
Allows concurrent fetches of user.
*/
function* mySaga() {
yield takeEvery("trigger", fetchUser);
}
/*
Alternatively you may use takeLatest.
Does not allow concurrent fetches of user. If "USER_FETCH_REQUESTED" gets
dispatched while a fetch is already pending, that pending fetch is cancelled
and only the latest one will be run.
*/
//function* mySaga() {
// yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
//}
const sagaMiddleware = createSagaMiddleware()
//////////////////////////////////////////
/////////////////////////////
// list.js
const List = (props) => (
<div>
{props.list.map(item => {
return (
<div>
{item.content}
<button onClick={() => props.remove(item.id)}>delete</button>
</div>
)
})}
</div>
);
// react-redux: connect get state from redux via Provider via react's context which allow child component to get upper component data
const ListContainer = connect(
function mapStateToProps(storeState){
return {list: storeState.todos }
},
function mapDispatchToProps(dispatch){
return {remove: function(id){
store.dispatch({type: "delete",id:id})
}}
})(List)
////////////////////////////
// logger.js
function stringify(obj){
return JSON.stringify(obj)
}
var history = [];
function logger({ getState }) {
return next => action => {
console.log('will dispatch', action)
const previousState = getState();
const previousStateStr = stringify(previousState)
history.push(previousStateStr)
// Call the next dispatch method in the middleware chain.
let returnValue = next(action)
console.log('state after dispatch', getState())
// This will likely be the action itself, unless
// a middleware further in chain changed it.
return returnValue
}
}
////////////////////////////////
// Redux store
const reducer = (state,action) => {
if( action.type === 'delete'){
//alert(action.id)
return {todos:state.todos.filter( e => e.id != action.id )}
}
if( action.type === 'USER_FETCH_SUCCEEDED'){
alert("tes");
}
if( action.type === 'undo'){
const state = JSON.parse( action.state );
if(state != null){
return state;
}
}
return state
}
const defaultState = {
todos: [{
id:1,
content: 'eat'
},{
id:2,
content: 'play'
}]
}
// Middleware
// wrap dispatch, like aop, action filter
// can do log, access control, undo/redo, replay
const middleware = applyMiddleware(logger,sagaMiddleware);
const store = createStore(reducer,defaultState,middleware)
sagaMiddleware.run(mySaga)
//////////////////////////////////
var App = () => (
<div>
<h1>Todo list</h1>
<button onClick={() => fetch()}>fetch</button>
<ListContainer />
</div>
)
function fetch(){
store.dispatch({type: "trigger",id:1})
}
function undo(){
store.dispatch({type: "undo",state: history.pop()})
}
render((
// react-redux: provider make redux store available to all connector component
<Provider store={store}>
<App/ >
</Provider>
), document.getElementById('root'));
import React from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import { createStore,applyMiddleware } from 'redux';
import { Provider, connect} from 'react-redux';
import createSagaMiddleware from 'redux-saga'
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
//////////////////////////////
// redux-saga-middleware.js
function someDelayCall(){
return new Promise( (res,rej) => {
setTimeout( () => res(), 2000)
})
}
function* fetchUser(action) {
try {
const user = yield call(someDelayCall, action.id);
yield put({type: "USER_FETCH_SUCCEEDED", user: user});
} catch (e) {
yield put({type: "USER_FETCH_FAILED", message: e.message});
}
}
/*
Starts fetchUser on each dispatched `USER_FETCH_REQUESTED` action.
Allows concurrent fetches of user.
*/
function* mySaga() {
yield takeEvery("trigger", fetchUser);
}
/*
Alternatively you may use takeLatest.
Does not allow concurrent fetches of user. If "USER_FETCH_REQUESTED" gets
dispatched while a fetch is already pending, that pending fetch is cancelled
and only the latest one will be run.
*/
//function* mySaga() {
// yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
//}
const sagaMiddleware = createSagaMiddleware()
//////////////////////////////////////////
/////////////////////////////
// list.js
const List = (props) => (
<div>
{props.list.map(item => {
return (
<div>
{item.content}
<button onClick={() => props.remove(item.id)}>delete</button>
</div>
)
})}
</div>
);
// react-redux: connect get state from redux via Provider via react's context which allow child component to get upper component data
const ListContainer = connect(
function mapStateToProps(storeState){
return {list: storeState.todos }
},
function mapDispatchToProps(dispatch){
return {remove: function(id){
store.dispatch({type: "delete",id:id})
}}
})(List)
////////////////////////////
// logger.js
function stringify(obj){
return JSON.stringify(obj)
}
var history = [];
function logger({ getState }) {
return next => action => {
console.log('will dispatch', action)
const previousState = getState();
const previousStateStr = stringify(previousState)
history.push(previousStateStr)
// Call the next dispatch method in the middleware chain.
let returnValue = next(action)
console.log('state after dispatch', getState())
// This will likely be the action itself, unless
// a middleware further in chain changed it.
return returnValue
}
}
////////////////////////////////
// Redux store
const reducer = (state,action) => {
if( action.type === 'delete'){
//alert(action.id)
return {todos:state.todos.filter( e => e.id != action.id )}
}
if( action.type === 'USER_FETCH_SUCCEEDED'){
alert("tes");
}
if( action.type === 'undo'){
const state = JSON.parse( action.state );
if(state != null){
return state;
}
}
return state
}
const defaultState = {
todos: [{
id:1,
content: 'eat'
},{
id:2,
content: 'play'
}]
}
// Middleware
// wrap dispatch, like aop, action filter
// can do log, access control, undo/redo, replay
const middleware = applyMiddleware(logger,sagaMiddleware);
const store = createStore(reducer,defaultState,middleware)
sagaMiddleware.run(mySaga)
//////////////////////////////////
var App = () => (
<div>
<h1>Todo list</h1>
<button onClick={() => fetch()}>fetch</button>
<ListContainer />
</div>
)
function fetch(){
store.dispatch({type: "trigger",id:1})
}
function undo(){
store.dispatch({type: "undo",state: history.pop()})
}
render((
// react-redux: provider make redux store available to all connector component
<Provider store={store}>
<App/ >
</Provider>
), document.getElementById('root'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment