React15 - 在redux应用中数据存储位置探讨

在React 15 + Redux的架构中,数据存储位置的选择主要遵循以下原则。针对你的场景,我来详细分析:

应该存储在 Redux store 中的数据

1. 表格列表数据

// 应该放在 Redux 中
{
  tableData: {
    list: [...],      // 表格数据
    total: 100,       // 总条数
    loading: false,   // 加载状态
    pagination: {     // 分页信息
      current: 1,
      pageSize: 10
    }
  }
}

原因:

  • 多个组件可能依赖这些数据
  • 需要跨页面/组件共享
  • 数据获取后可能需要缓存

2. 弹窗表单提交后的数据(如果需要全局展示)

  • 新添加的数据如果立即在表格中显示
  • 可能被其他组件使用的表单提交结果

应该存储在组件 state 中的数据

1. 弹窗的 UI 状态

class PageComponent extends React.Component {
  state = {
    modalVisible: false,  // 弹窗显示状态
    confirmLoading: false, // 提交按钮加载状态
    formData: {}          // 临时表单数据(如果不需要全局保存)
  }
}

原因:

  • 弹窗的显隐是纯粹的 UI 状态
  • 只影响当前组件,不需要共享

2. 表单临时数据

state = {
  formValues: {
    name: '',
    age: '',
    email: ''
  }
}

原因:

  • 表单填写是临时行为
  • 取消弹窗后这些数据应该被清除
  • 只有提交成功后的数据才需要存入 Redux

实际代码示例

import React from 'react';
import { connect } from 'react-redux';
import { fetchTableData, addTableRow } from './actions';

class TablePage extends React.Component {
  state = {
    modalVisible: false,
    formData: {
      name: '',
      age: '',
      email: ''
    },
    submitting: false
  };

  componentDidMount() {
    // 获取表格数据 - 存入 Redux
    this.props.fetchTableData();
  }

  // 处理表单输入变化 - 存在组件 state
  handleInputChange = (e) => {
    this.setState({
      formData: {
        ...this.state.formData,
        [e.target.name]: e.target.value
      }
    });
  };

  // 提交表单 - 成功后存入 Redux
  handleSubmit = () => {
    this.setState({ submitting: true });
    
    this.props.addTableRow(this.state.formData)
      .then(() => {
        this.setState({
          modalVisible: false,
          formData: {},  // 清空表单数据
          submitting: false
        });
      })
      .catch(() => {
        this.setState({ submitting: false });
      });
  };

  // 关闭弹窗 - 清除临时数据
  handleCancel = () => {
    this.setState({
      modalVisible: false,
      formData: {}  // 取消时清空表单
    });
  };

  render() {
    // 表格数据来自 Redux
    const { tableData, loading } = this.props;
    // UI 状态来自组件 state
    const { modalVisible, formData, submitting } = this.state;

    return (
      <div>
        {/* 表格组件 - 使用 Redux 数据 */}
        <Table 
          dataSource={tableData.list}
          loading={loading}
          pagination={tableData.pagination}
        />
        
        {/* 添加按钮 */}
        <Button onClick={() => this.setState({ modalVisible: true })}>
          添加数据
        </Button>

        {/* 弹窗表单 - 使用组件 state */}
        <Modal
          visible={modalVisible}
          onCancel={this.handleCancel}
          onOk={this.handleSubmit}
          confirmLoading={submitting}
        >
          <Form>
            <Input 
              name="name"
              value={formData.name}
              onChange={this.handleInputChange}
            />
            {/* 其他表单项 */}
          </Form>
        </Modal>
      </div>
    );
  }
}

const mapStateToProps = (state) => ({
  tableData: state.tableData,
  loading: state.loading
});

const mapDispatchToProps = {
  fetchTableData,
  addTableRow
};

export default connect(mapStateToProps, mapDispatchToProps)(TablePage);

核心原则

  1. 共享数据 → Redux

    • 表格数据(多个组件可能使用)
    • 用户信息(全局需要)
    • 应用配置(跨页面共享)
  2. 临时数据 → 组件 state

    • 弹窗显隐状态
    • 表单输入值(未提交前)
    • 组件内部的加载状态
  3. 需要考虑的因素

    • 数据生命周期:页面关闭后是否需要保留
    • 使用范围:是否被多个组件使用
    • 更新频率:高频更新的 UI 状态适合放在本地 state

这样的设计既能保证数据的可预测性,又能避免不必要的 Redux 状态臃肿。

posted @ 2026-03-15 22:52  箫笛  阅读(0)  评论(0)    收藏  举报