Created
August 11, 2017 13:25
-
-
Save kittolau/93620f3f50200d95d6a082b9ef04fbdb to your computer and use it in GitHub Desktop.
react
This file contains 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 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