javascript - 如何在 React 中管理同一页面上的多个相同组件及其各自单独的 axios 请求?

标签 javascript reactjs react-redux

我有 React-Redux 应用程序,我想制作它的仪表板,在上面显示多个相同的组件,让我解释一下我的应用程序更广泛的结构是什么样的

  1. commonPage 根组件,其中包含另外 2 个组件

    1. CommonContent(显示表格)

    2. CommonContentView(显示相应表格的编辑字段)

每个组件都在其构造函数中发出请求,以返回数据

我的网站 每个页面一次仅显示一个组件,或者显示 CommonContentCommonContentView 组件工作得很好。

当我在一页上多次显示相同的组件时,出现了我的主要问题 这是仪表板组件结构,在一个页面上显示多个 CommonContent 组件

  • Dashboard 根组件,其中包含 1 个其他组件

    1. DashboardItem(它映射我的数组列表,其中包含每个表的详细信息)

      1. DashboardContent(显示与 CommonContent 组件相同的表格)

让我分享 Dashboard 组件的代码片段

/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 >
    )

}

仪表板内容

/* 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)
);

当我在页面上显示多个表时,上面的一切都工作正常,它对每个表使用 DashboardContent ,它为每个通过 redux 处理的单独查询发送请求

如果页面上呈现两个表格并发送 2 个请求 当收到响应时,它会映射到两个表,而不是将数据映射到各自的表

我觉得这是由于 redux,因为发出的每个请求都会将其响应映射到 state 中的一个 data var 这是来自 DashboardContent.js 文件的引用

function mapStateToProps(state, ownProps) {
      return {
        data: state.data
      };
    }

    function mapDispatchToProps(dispatch) {
      return {
        common: bindActionCreators(actions.dataActions, dispatch)
      };
    }

在每个请求响应上,此mapStateToProps 起作用并将响应数据映射到状态数据 它不应该更新发出 DashboardContent.js 请求的特定表

现在简而言之,我有多个带有自己的请求数据的 DashboardContent.js 这是试图解释页面上多个表的行为方式的示例

`DashboardContent.js` -> contains query regarding users
`DashboardContent.js` -> contains query regarding rooms
`DashboardContent.js` -> contains query regarding units 

现在,当任何这些请求的请求完成时,例如,我说房间请求已解决,房间数据将映射到上述所有 DashboardContent.js 表上,这些表应仅将数据映射到其各自的表 所有查询的行为方式相同,最后解析的请求通常映射在表上 这是显示感染表查询最后完成的图像,并将其数据映射到两个表 enter image description here

我希望我能够传达我的问题 我需要为单独的表创建每个 redux 存储,还是必须为每个表创建唯一的表组件(这将降低动态性并且违反 DRY 原则),除此之外,我还有什么地方做错了?您对这个问题的帮助将是全面的,因为它是正在进行的工作项目,快速的帮助将是伟大的

最佳答案

据我所知,您正在使用相同的组件来调用不同的 api。我建议将数据的 View 部分作为不同的组件,我认为这对于所有 3 种类型的数据来说都是相似的,并且进行 api 调用的容器应该是 3 个不同的组件,具有单独的 api 调用和单独的 redux 存储,以便他们不会修改彼此的数据。由于相同的 redux 存储,所有修改它并且它们都接收相同的数据。

关于javascript - 如何在 React 中管理同一页面上的多个相同组件及其各自单独的 axios 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58426985/

相关文章:

javascript - 还原。我无法理解如何连接定义为扩展 React.Component 的类的组件以便读取存储

react-native - 我可以在我的 React Native 应用程序中使用 Flutter 吗?

javascript - 滚动和 .addClass();问题

javascript - .jshintrc 文件未被读取

Javascript 合并对象数组中的重复项

reactjs - 什么是 React ...Capture 事件?

reactjs - 无法读取 ReactJS Redux 表单中未定义错误的属性 'parentNode'

react-native - 防止快速单击按钮时导航两次

javascript - 添加没有html的文本悬停图像

javascript - 如果文本与 jQuery 中的字符串匹配,则删除元素