I’m currently building a simple chat feature in my app using redux saga. Chat successfully entered from the emit server to the client
But the problem is, so when I move from the chat page and then back to the chat page, the last chat data sent will be duplicated to 2. Then when I move again and return to the chat page, the sent chat will be 3 and so on.
i think this happened maybe because the listener loop on fetchKonsultasi() function was stacked
Here is a dispatch function onGetKonsultasi() to listen to emits and onGetListKonsultasi() to retrieve chat list data from the server. Chat data is stored in the dataListKonsultasi, when there is an issue from the server, the dataListKonsultasi state will be updated
Someone help me, I really appreciate your help
index.js
useEffect(() => {
onGetListKonsultasi()
onGetKonsultasi()
}, [])
------
Konsultasi.propTypes = {
dataKonsultasi: PropTypes.object,
dataListKonsultasi: PropTypes.object,
onGetKonsultasi: PropTypes.func,
onGetListKonsultasi: PropTypes.func,
}
const mapStateToProps = ({ konsultasiReducer }) => ({
dataKonsultasi: konsultasiReducer.dataKonsultasi,
dataListKonsultasi: konsultasiReducer.dataListKonsultasi,
})
const mapDispatchToProps = dispatch => ({
onGetKonsultasi: () => dispatch(getKonsultasi()),
onGetListKonsultasi: () => dispatch(getListKonsultasi()),
})
export default connect(mapStateToProps, mapDispatchToProps)(Konsultasi)
saga.js
function createSocketConnection(url) {
return io(url)
}
function createSocketChannel(socket) {
return eventChannel(emit => {
const eventHandler = event => {
emit(event)
}
const errorHandler = errorEvent => {
emit(new Error(errorEvent.reason))
}
socket.on("AdminReceiveMessage", eventHandler)
socket.on("error", errorHandler)
const unsubscribe = () => {
socket.off("AdminReceiveMessage", eventHandler)
}
return unsubscribe
})
}
function* fetchKonsultasi() {
const socket = yield call(createSocketConnection, env.SOCKET_URL)
const socketChannel = yield call(createSocketChannel, socket)
while (true) {
try {
const response = yield take(socketChannel)
yield put(updateListKonsultasiSuccess(response))
} catch (err) {
console.log("socket error: ", err)
}
}
}
function* fetchListKonsultasi() {
try {
const response = yield call(getListKonsultasi)
yield put(getListKonsultasiSuccess(response))
} catch (error) {
yield put(getListKonsultasiFail(error))
}
}
export function* watchSocket() {
yield takeEvery(GET_KONSULTASI, fetchKonsultasi)
yield takeEvery(GET_LIST_KONSULTASI, fetchListKonsultasi)
}
function* konsultasiSaga() {
yield all([fork(watchSocket)])
}
reducer.js
case GET_LIST_KONSULTASI_SUCCESS:
return {
...state,
dataListKonsultasi: action.payload,
}
case UPDATE_LIST_KONSULTASI_SUCCESS:
return {
...state,
dataListKonsultasi: {
users: { ...state.dataListKonsultasi.users },
data: [...state.dataListKonsultasi.data, action.payload],
},
dataListKonsultasi Structure :
{
"users": {
......
},
"data": [
{
..chat_data...
},
{
..chat_data...
},
]
}