Reputation: 1242
Having a strange bug/issue with redux. I have a component in an app that displays data in a table. this table is used across numerous routes and i'm passing in a url for the end point.
When i click between the routes they work fine but some fields in the table have a button to open a slide out menu. when i do the redux actions is dispatched and it fires it for all routes i have been to and not the one i'm on.
Action
export const clearTableData = () => dispatch => {
dispatch({
type: TYPES.CLEAR_TABLE_DATA,
});
};
export const getTableData = (url, limit, skip, where, sort, current) => async dispatch => {
try {
dispatch({ type: TYPES.FETCH_TABLE_DATA_LOADING });
const response = await axios.post(url, {
limit,
skip,
where,
sort
});
await dispatch({
type: TYPES.FETCH_TABLE_DATA,
payload: {
url: url,
data: response.data,
limit: limit,
skip: skip,
where: where,
sort: sort,
pagination: {
total: response.data.meta.total,
current: current,
pageSizeOptions: ["10", "20", "50", "100"],
showSizeChanger: true,
showQuickJumper: true,
position: "both"
}
}
});
dispatch({ type: TYPES.FETCH_TABLE_DATA_FINISHED });
} catch (err) {
dispatch({ type: TYPES.INSERT_ERROR, payload: err.response });
}
};
Reducer
import * as TYPES from '../actions/types';
export default (state = { loading: true, data: [], pagination: [] }, action) => {
switch (action.type) {
case TYPES.FETCH_TABLE_DATA:
return { ...state, ...action.payload };
case TYPES.FETCH_TABLE_DATA_LOADING:
return { ...state, loading: true };
case TYPES.FETCH_TABLE_DATA_FINISHED:
return { ...state, loading: false };
case TYPES.CLEAR_TABLE_DATA:
return {};
default:
return state;
}
};
component
componentDidMount() {
this.fetch();
websocket(this.props.websocketRoute, this.props.websocketEvent, this.fetch);
}
fetch = () => {
// Fetch from redux store
this.props.getTableData(
this.props.apiUrl,
this.state.limit,
this.state.skip,
{ ...this.filters, ...this.props.defaultWhere },
`${this.state.sortField} ${this.state.sortOrder}`,
this.state.current)
}
const mapStateToProps = ({ tableData }) => ({
tableData,
});
const mapDispatchToProps = dispatch => (
bindActionCreators({ getTableData }, dispatch)
)
export default connect(
mapStateToProps,
mapDispatchToProps
)(SearchableTable);
Websocket
import socketIOClient from 'socket.io-client';
import sailsIOClient from 'sails.io.js';
export const websocket = (websocketRoute, websocketEvent, callback) => {
if (websocketRoute) {
let io;
if (socketIOClient.sails) {
io = socketIOClient;
} else {
io = sailsIOClient(socketIOClient);
}
io.sails.transports = ['websocket'];
io.sails.reconnection = true;
io.sails.url = process.env.REACT_APP_WEBSOCKECTS_URL
io.socket.on('connect', () => {
io.socket.get(websocketRoute, (data, jwres) => {
console.log("connect data sss", data)
console.log("connect jwres sss", jwres)
});
});
io.socket.on(websocketEvent, (data, jwres) => {
console.log("websocket", callback)
callback();
})
io.socket.on('disconnect', () => {
io.socket._raw.io._reconnection = true;
});
}
}
So for e.g if i'm on a route for cars i'll pass in api/cars as url, and for trucks api/trucks. if i've been to both these pages they get fired. should i be doing something to unmount and reset state to blank?
edit to add render
render() {
const { filters, columns, expandedRowRender, rowClassName, style } = this.props;
return (
<Table
bordered
columns={columns}
rowKey={record => record.id}
dataSource={this.props.tableData.data.items}
pagination={this.props.tableData.pagination}
loading={this.props.tableData.loading}
onChange={this.handleTableChange}
expandedRowRender={expandedRowRender}
rowClassName={rowClassName} />
);
Upvotes: 3
Views: 12905
Reputation: 104369
Basic idea is, define a new action type in reducer file to clear the table data, and before unmount dispatch that action.
In Component:
componentDidMount() {
this.fetch();
}
componentWillUnmount() {
this.props.clearTableData();
}
const mapDispatchToProps = dispatch => (
bindActionCreators({ getTableData, clearTableData }, dispatch)
)
Action:
export const clearTableData = () => {
return { type: TYPES.CLEAR_TABLE_DATA };
};
Reducer:
case TYPES.CLEAR_TABLE_DATA: {
// reset the table data here, and return
}
Upvotes: 4