【问题标题】:Redux: Should i clear state on unmountRedux:我应该在卸载时清除状态
【发布时间】:2019-03-28 00:47:38
【问题描述】:

redux 有一个奇怪的错误/问题。我在应用程序中有一个在表格中显示数据的组件。该表用于许多路线,我正在为终点传递一个 url。

当我在路线之间单击时,它们工作正常,但表中的某些字段有一个按钮可以打开滑出菜单。当我执行 redux 操作时,它会为我去过的所有路线而不是我所在的路线触发它。

动作

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 });
  }
};

减速器

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;
  }
};

组件

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

网络套接字

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;
    });
  }
}

因此,例如,如果我在汽车路线上,我将通过 api/cars 作为 url 传递,而对于卡车 api/trucks。如果我去过这两个页面,他们就会被解雇。 我应该做些什么来卸载并将状态重置为空白吗?

编辑以添加渲染

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

    );

【问题讨论】:

  • 这将是一个选项,在组件卸载或安装新组件之前清除减速器。
  • 你能举例说明如何做到这一点吗@MayankShukla

标签: reactjs redux react-redux


【解决方案1】:

基本思路是,在reducer文件中定义一个新的action类型来清空表数据,在unmount前dispatch那个action。

在组件中:

componentDidMount() {
  this.fetch();
}

componentWillUnmount() {
  this.props.clearTableData();
}

const mapDispatchToProps = dispatch => (
  bindActionCreators({ getTableData, clearTableData }, dispatch)
)

行动:

export const clearTableData = () => {
  return { type: TYPES.CLEAR_TABLE_DATA };
};

减速机:

case TYPES.CLEAR_TABLE_DATA: {
  // reset the table data here, and return
}

【讨论】:

  • 刚刚尝试过类似的方法并没有解决问题,我可以在 redux 开发工具中看到它正在清除它,但是当我单击按钮打开滑出部分时,它会显示以前的路线数据.这可能与路由器历史有关吗?
  • 不,你能展示一下你是如何在表格中渲染数据的吗?我的意思是你是直接使用道具数据还是将道具数据存储在状态然后使用它?
  • 在你返回的减速器中?
  • 我已更新我的问题以显示明确的操作及其减速器。
  • 我已经更新了问题,因为它似乎是导致问题的 websockets,有什么想法吗?
猜你喜欢
  • 2021-04-13
  • 1970-01-01
  • 1970-01-01
  • 2016-08-03
  • 2021-04-27
  • 1970-01-01
  • 2022-07-14
  • 2018-08-02
  • 1970-01-01
相关资源
最近更新 更多