【问题标题】:Memory reference issue for function return (React Javascript)函数返回的内存参考问题(React Javascript)
【发布时间】:2020-12-29 19:20:54
【问题描述】:

所以我在 React.js 工作。我需要生成同一个列表的三个版本,但三个事件中的每一个都包含一组不同的市场。 我希望事件是相同的。但是,当它们与市场相关联时,这三个相同事件中的每一个都可能具有基于申报者的不同市场子集。

organiseEvents(timeFilter) {
    const propevents = this.props.Properties.events;
    const propmarkets = this.props.Properties.markets;
    const propselections = this.props.Properties.selections;

    let events = new Array();

    propevents.forEach(e => {
        e.Markets = propmarkets.filter(m => m.Values.eventid === e.Id && m.Values.name.toUpperCase().includes(timeFilter));
        e.Markets.forEach(m => {
            m.Selections = propselections.filter(s => s.Values.marketid === m.Id);
        });

        events.push(e);
    });

    if(events.length > 0) {
    events = events.sort(function (a, b) { return a.Values.homerotation - b.Values.homerotation });
    return events;
    } else{
    return [];
    }
}

render() {
    let events = this.organiseEvents("");
    let midevents = this.organiseEvents("MIDEVENT");
    let postevents = this.organiseEvents("POSTEVENT");
}

我遇到的问题是:

  • this.organiseEvents("") 运行:事件包含两个“事件”对象,每个对象包含三个市场。
  • this.organiseEvents("MIDEVENT") 运行:midevents 包含相同的两个“事件”对象,但没有市场,因为没有市场与过滤器匹配。
  • events 也成为 this.organiseEvents("MIDEVENT") 的结果。
  • events 和 midevents 将成为 this.organiseEvents("POSTEVENT") 的结果

某处有一个参考问题,我终生无法发现它。我觉得我错过了显而易见的事情。

每三个 let 变量应该是相同两个事件的三个​​完全独立的表示,但其中包含不同的市场。

我同时发现的一个修复方法如下:

    let events = JSON.parse(JSON.stringify(this.organiseEvents("")));
    let midevents = JSON.parse(JSON.stringify(this.organiseEvents("MIDEVENT")));
    let postevents = JSON.parse(JSON.stringify(this.organiseEvents("POSTEVENT")));

这会强制三个值中的每一个不引用同一个地方。但是,在我看来,这是一个肮脏的解决方案,它可以方便地解决问题,而不是让我了解问题所在并正确解决问题。

谢谢。

【问题讨论】:

  • 您的问题是由于const propevents = this.props.Properties.events;e.Markets = propmarkets.filter....; 3 行中的引用问题。和m.Selections = propselections.filter.... 每次调用this.organizeEvents 时,您从道具中引用相同的数组,即Properties.events。并且您使用 e.Markets = propmarkets.filter....m.Selections = propselections.filter... 改变该数组。

标签: javascript reactjs function memory return


【解决方案1】:

每次调用organizeEvents 函数时,它只是使用相同的数组并对其进行变异/更改。

同一个数组在哪里使用?

const propevents = this.props.Properties.events; // (Properties.events) is an array that you are mutating

在这里,您刚刚将数组分配给变量propevents。这并不意味着将数组复制到变量中。变量只是引用同一个数组。

数组在哪里变异/改变了?

1.

propevents.forEach(e => { 
   e.Markets = propmarkets.filter(m => m.Values.eventid === e.Id && m.Values.name.toUpperCase().includes(timeFilter));

在这里,您正在循环遍历 propevents 数组,并为该数组中的每个元素更改/更改属性 Markets(这是一个数组)。

2.

e.Markets.forEach(m => {
        m.Selections = propselections.filter(s => s.Values.marketid === m.Id);
    });

在这里,您再次循环遍历上述变异/更改的Markets,并且对于Markets 数组中的每个元素,您正在变异/更改属性Selections(这也是一个数组)。

解决方案

这个问题的解决方案是对数组进行深拷贝并对其进行变异/更改。

如何

  1. 您可以创建一个实用函数来深度复制数组和对象。

     // it's not the best but it does the job
       function deepCopy(o) {
          let output, v, key;
          output = Array.isArray(o) ? [] : {};
          for (key in o) {
            v = o[key];
            output[key] = typeof v === "object" && v !== null ? deepCopy(v) : v;
          }
          return output;
        };
    
    
  2. organizeEvents 函数中使用它

     const propevents = deepCopy(this.props.Properties.events);
    

【讨论】:

    猜你喜欢
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多