动态生成反应组件中的svg defs可能会导致内存泄漏

时间:2017-05-23 06:43:13

标签: reactjs svg memory-leaks frontend data-visualization

我正在研究一个svg动画,它需要动画中动态生成svg渐变,因为动画正在进行中。

但似乎浏览器即使在它之后也不会释放内存 已经被React使用或从dom中移除。

经过数小时的研究后,我发现如果渐变元素的id为无限范围(例如Math.random),就会发生这种情况。

现在我的问题是如何在没有浏览器重新加载的情况下释放内存?

感谢。

demo

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className="App">
        <svg width="1000" height="500">
          <Tt></Tt>
        </svg>
      </div>
    );
  }
}


class Tt extends React.Component {
  constructor(props) {
    super(props);
    this.timer = null;
    this.state = {
      id: 0
    };
  }

  componentDidMount() {
    let loop = () => {
      this.setState({
        id: this.state.id + 1
      }, () => {
        window.requestAnimationFrame(loop);        
      });
    };

    loop();
  }

  render() {
    let arr = [];

    for(let i = 0; i <= 1000; i++){
      arr.push(Math.random());
    }

    return <g>
      <defs>
        {
          arr.map((randomnum, i) => {
            // define defs gradient with random id
            return (
              <linearGradient id={`r${randomnum}`}>
                <stop offset="20%" stopColor="#39F" />
                <stop offset="90%" stopColor="#F3F" />
              </linearGradient>
            )
            // -----problem solved if use i as id---
            // return (
            //   <linearGradient id={`r${i}`}>
            //     <stop offset="20%" stopColor="#39F" />
            //     <stop offset="90%" stopColor="#F3F" />
            //   </linearGradient>
            // )
          })
        }
      </defs>
      <g>
      {
        arr.map((randomnum, i) => {
          // use gradient with random id
          return <rect x={Math.random()*1000} y={Math.random()*500} width="100" height="100" fill={`url(#r${randomnum})`}></rect>
          // -----problem solved if use i as id---
          // return <rect x={Math.random()*1000} y={Math.random()*500} width="100" height="100" fill={`url(#r${i})`}></rect>

        })
      }
      </g>
    </g>
  }
}
ReactDOM.render(
  <App /> ,
  document.getElementById('root')
);

enter image description here

0 个答案:

没有答案