Created
January 26, 2020 00:31
-
-
Save compulim/51676ea9798a5156db8beb3c97edd8a6 to your computer and use it in GitHub Desktop.
useReducerWithSaga
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 { useCallback } from 'react'; | |
import useReducerWithSaga from './useReducerWithSaga'; | |
import saga from '../data/saga'; | |
const DEFAULT_STATE = { | |
localStream: null, | |
remoteStreams: [] | |
}; | |
function reducer(state, action) { | |
switch (action.type) { | |
case 'CONNECT_FULFILLED': | |
state = { ...state, connected: true }; | |
break; | |
case 'DISCONNECT': | |
state = { ...state, connected: false }; | |
break; | |
case 'SET_LOCAL_STREAM': | |
state = { ...state, localStream: action.payload.stream }; | |
break; | |
case 'ADD_REMOTE_STREAMS': | |
state = { ...state, remoteStreams: [...state.remoteStreams, ...action.payload.streams] }; | |
break; | |
default: | |
break; | |
} | |
return state; | |
} | |
export default function useApp2() { | |
const [state, dispatch] = useReducerWithSaga(reducer, DEFAULT_STATE, saga); | |
const handleConnectClick = useCallback(() => dispatch({ type: 'CONNECT' }), [dispatch]); | |
const handleDisconnectClick = useCallback(() => dispatch({ type: 'DISCONNECT' }), [dispatch]); | |
return [ | |
{ | |
localStream: state.localStream, | |
readyState: state.connected ? 'connected' : 'idle', | |
remoteStreams: state.remoteStreams | |
}, | |
{ | |
handleConnectClick, | |
handleDisconnectClick | |
} | |
]; | |
} |
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 { useCallback, useEffect, useMemo, useReducer, useRef } from 'react'; | |
import { eventChannel, runSaga, END } from 'redux-saga'; | |
export default function useReducerSaga(reducer, initialState, saga) { | |
const [state, dispatch] = useReducer(reducer, initialState); | |
const getStateRef = useRef(() => state); | |
const sagaEmitterRef = useRef(); | |
const channel = useMemo( | |
() => | |
eventChannel(emitter => { | |
sagaEmitterRef.current = emitter; | |
return () => { | |
sagaEmitterRef.current = null; | |
}; | |
}), | |
[] | |
); | |
useEffect(() => { | |
const task = runSaga({ channel, dispatch, getState: getStateRef.current }, saga); | |
return () => { | |
sagaEmitterRef.current(END); | |
task.end(); | |
}; | |
}, [channel, saga]); | |
const dispatchWithSaga = useCallback( | |
action => { | |
dispatch(action); | |
sagaEmitterRef.current(action); | |
}, | |
[] | |
); | |
return [state, dispatchWithSaga]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment