I have React-Redux Application I wanted to make its dashboard on which it will display multiple same components, let me explain how my application broader structure looks like
commonPageroot component which holds 2 further components in itCommonContent(Which displays Table)CommonContentView(which displays Edit fields for respective table)
Each of these components have request being made in their constructor which brings data back
My Website Each page display only one component at one time either it shows CommonContent OR CommonContentView Component which works perfectly fine.
My Main issue raised when I display same component multiple times on one page
here is dashboard components structure which shows multiple CommonContent component on one page
Dashboardroot component which holds 1 further component in itDashboardItem(it maps my list of array which holds detail about each table)DashboardContent(which displays table same likeCommonContentcomponent)
Let me share code snippet from Dashboard components
/dashboard.js
class Dashboard extends Component {
constructor(props, context) {
super(props, context);
this.url = this.props.match.url;
this.entity = this.url === '/' ? 'customers' : this.url.split('/')[1];
this.model = getModel(this.entity);
}
render() {
const { classes } = this.props;
return (
<Wrapper>
<FilterBar title={this.model.entity.title} entity={this.entity} history={this.props.history} />
<div className={classes.root}>
{this.model.entities.map(e => <DashboardItem entity={e.entity} table={e} />)}
</div>
</Wrapper>
)
}
}
./dashboardItem.js
render() {
let { classes } = this.props
return (
<Wrapper>
<FilterBar title={this.model.entity.title} entity={this.entity} history={this.props.history} dashboard={true} table={this.props.table} />
<div className={classes.root}>
<Card className={classes.card}>
<CardContent className={classes.content}>
<DashboardContent
model={this.model}
entity={this.entity}
formDialog={ref => (this.formDialog = ref)}
show={this.show}
handleUpdateFilters={this.handleUpdateFilters}
onRef={ref => (this.reload = ref)}
table={this.props.table}
/>
</CardContent>
</Card >
</div >
</Wrapper >
)
}
DashboardContent
/* eslint-disable */
// import CustomerView from "../pages/Material/customerView";
import React from 'react';
import actions from '../../actions/index';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import HTtable from '../../utils/dataTables/HTtable';
import { getQuery } from '../../utils/common/queries';
import FormDialog from '../../components/common/formDialog';
import * as F from '../../utils/common/functions';
import * as service from '../../services/customService';
import toast from '../../utils/common/toastr';
import Spinner from '../../components/common/spinner';
import * as R from 'ramda';
class DashboardContent extends React.Component {
constructor(props, context) {
super(props, context);
this.query = getQuery({ label: this.props.entity });
this.state = {
order: 'desc',
orderBy: 'id',
currentSelected: -1,
data: [],
meta: { count: 0 },
page: 0,
prevSkip: 0,
rowsPerPage: 10,
rowsPerPageOptions: [1],
dialog: {
state: false,
dialog: {
title: '',
desc: ''
}
},
entity: this.props.entity,
rawKeys: this.props.model.keys,
actions: this.props.model.actions,
reloadData: this.props.reloadData,
currentQuery: this.query,
spinner: true,
tableData: this.props.table.data,
table: this.props.table
};
this.query = R.isEmpty(F.getItem(this.props.entity).where)
? this.query
: F.addFilterWhere(this.state, F.getItem(this.props.entity).where);
this.props.common.getData(this.query);
}
componentDidMount = () => {
this.props.onRef(this);
};
componentWillReceiveProps = nextProps => {
if (nextProps.data !== this.props.data) {
if (nextProps.data.error) {
toast.error(nextProps.data.error.message);
if (nextProps.data.error.code === 401) {
F.removeSession();
this.props.history.push('/signin');
}
this.setState({ spinner: false });
} else {
this.setState({
currentQuery: this.query,
data: nextProps.data['records'],
meta: nextProps.data['meta'],
spinner: false
});
}
}
};
render() {
return (
<div>
<Spinner show={this.state.spinner} />
<FormDialog
formDialog={this.props.formDialog}
handleClick={this.handleClick}
{...this.state}
reloadData={this.reloadData}
state={this.state}
show={true}
/>
{/*<CreateForm ref={this.props.create} {...this.state} keys={this.state.create_keys} show={true}/>*/}
<HTtable
state={this.state}
props={this.props}
isSelected={this.isSelected}
handleRequestSort={this.handleRequestSort}
handleClick={this.handleClick}
displayData={this.displayData}
handleChangePage={this.handleChangePage}
handleMetaSkip={this.handleMetaSkip}
handleChangeRowsPerPage={this.handleChangeRowsPerPage}
handleDialog={this.handleDialog}
dashboard={'true'}
/>
</div>
);
}
}
DashboardContent.propTypes = {
// classes: PropTypes.object.isRequired
};
function mapStateToProps(state, ownProps) {
return {
data: state.data
};
}
function mapDispatchToProps(dispatch) {
return {
common: bindActionCreators(actions.dataActions, dispatch)
};
}
export default withRouter(
connect(
mapStateToProps,
mapDispatchToProps
)(DashboardContent)
);
Everything above works fine real issue when I display multiple tables on page it uses DashboardContent for each table, which sends request for each seperate query which is handled through redux
if two tables are rendered on page and 2 requests are sent when response is received it is mapped over both tables instead of mapping data to it respective table
I feel this is due to redux because each requests which were made they mapped their response to one data var in state
here is reference from DashboardContent.js file
function mapStateToProps(state, ownProps) {
return {
data: state.data
};
}
function mapDispatchToProps(dispatch) {
return {
common: bindActionCreators(actions.dataActions, dispatch)
};
}
here on each request response this mapStateToProps act and map response data to state data
shouldn't it update that specific table in which DashboardContent.js request is made
now in short I have multiple DashboardContent.js with their own request data
here is example trying to explain multiple table on page how behaves
`DashboardContent.js` -> contains query regarding users
`DashboardContent.js` -> contains query regarding rooms
`DashboardContent.js` -> contains query regarding units
now when request is completed for any of those requests for instance I say rooms request is resolved and rooms data wull mapped on all above DashboardContent.js tables which should map data only to its respective table
same way all queries behave which request resolve at last usually maps on tables
here is image which shows infections table query is completed last and it mapped its data over both tables
I hope I was able to convey my Question What will be possible solutions for this do I need to create each redux store for separate table or do I have to create unique table components for each table(which will be less dynamic and against DRY principle) other then this where else I am doing wrong Your help regarding this issue will be help full as it is on going job project, quick help will be great