React 教程第十五篇 —— 项目应用

本文介绍了一个使用Redux中间件实现组件数据动态加载并解决作用域冲突问题的案例。通过为每个数据源指定唯一别名,确保不同组件间的数据独立加载,避免数据污染。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现

该案例是以中间件调用 nodejs 的公共接口,实现一个数据列表。

源码下载:https://github.com/dk-lan/rea...

效果预览

用户名和密码都为空

源码下载后执行下面步骤例可查看效果

  • npm install
  • npm start

Redux 中间件的问题之作用域

在 Redux 中使用中间件可以解决很多问题,但也会有个致命的问题,那就是在同一个组件中多次调用同一个组件,那就会造成作用域污染。

本案例中是这样的场景:

  • 现在要实现在组件cnode中动态加载数据,在该组件中还会有一个输入框,点击时弹窗动态加载一个数据列表,双击数据列表进行填充到对应的输入框中
  • 有一个组件datagrid,用于动态加载数据,ajax 加载使用了中间件。
  • 有一个组件modal,该组件用到弹窗加载一个数据列表datagrid
  • 在组件cnode中调用了组件datagrid<Datagrid config={this.props.cnode.config}/>
  • 在组件cnode中同时调用了组件modal,而组件modal又调用了组件datagrid
  • 这个时候两个datagrid的数据源就会冲突,后面加载的数据冲突了前面加载的。
  • 解决方案是在数据源中对数据源作用域隔离

对象作用域隔离

每次调用组件datagrid时给一个别名name,别名不能重复,用于作用域隔离
static defaultProps = {
    cnode: {
        config: {
            url: 'https://cnodejs.org/api/v1/topics',
            data: {page: 1, limit: 10},
            cols: ['title', 'reply_count', 'top', 'create_at', 'last_reply_at'],
            name: 'cnode'
        }           
    },
    modal: {
        config: {
            type: 'datagrid',
            url: 'https://cnodejs.org/api/v1/topics',
            data: {page: 3, limit: 5},
            cols: ['title'],
            name: 'modal'
        } 
    }
}
Action 中将别名name派发到中间件
export function refresh(_config){
    return {
        types: [constants.Requesting, constants.Requested, constants.RequestError],
        url: _config.url,
        method: _config.method || 'get',
        data: _config.data || {},
        name: _config.name
    }
}
在中间件将别名name一派发到Reducer
let _action = {
    type: constants.Requested,
    name,
    result: res.data
}
dispatch(_action)
Reducer中兼容有别名和没别名的情况,如果有别名,就将数据源作用域隔离
if(action.name){
    _state[action.name] = _state[action.name] || {};
    _state[action.name].dataset = action.result;
} else {
    _state.dataset = action.result;
}
DatagridComponent中判断是否有别名,兼容有别名和没别名的情况,分别操作不同的数据源
let ds = this.props.dataset;
let name = this.props.config.name;
if(name){
    ds = ds[name] ? ds[name].dataset : []
} else {
    ds = ds.dataset || [];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值