是否通过props将对象传递给子反应组件,克隆原始对象或通过引用传递?

Str*_*ch0 8 javascript reactjs

如果要通过组件props将对象传递给子组件,是否会克隆此对象,或者只是将引用传递给原始对象?

例如,我App.js在导入一个JSON对象ENTRY_DATA.然后我通过props将该对象传递给我的子组件(或者在这种情况下,路由).我是通过这样做来节省内存还是像我要ENTRY_DATA在每个组件上导入一样?

import React, { Component } from 'react';
import { withRouter, Route } from 'react-router-dom'
import ENTRY_DATA from './../../entry_data.json';


import Register from '../Register/Register';
import Categories from '../Categories/Categories';
import Category from '../Category/Category';
import Entry from '../Entry/Entry';

class App extends Component {

  render() {

    return (
      <div className="app" >

        <main>
          <Route exact path="/" component={Register} />
          <Route exact path='/categories' render={(props) => (
            <Categories {...props} categories={ENTRY_DATA} />
          )}/>
          <Route exact path='/categories/:category' render={(props) => (
            <Category {...props} categories={ENTRY_DATA} />
          )}/>
          <Route exact path='/categories/:category/:entry' render={(props) => (
            <Entry {...props} categories={ENTRY_DATA} />
          )}/>
        </main>

      </div>
    );
  }
}

export default withRouter(App);
Run Code Online (Sandbox Code Playgroud)

如果ENTRY_DATA是5kb,并且我将它传递给3个不同的组件,这是否意味着我最终得到20kb的价值ENTRY_DATA或者他们都参考了5kb ENTRY_DATA

Chr*_*ris 9

通常,它取决于所述道具的数据类型.整数(如整数字符串)按其值传递,而对象数据类型(如数组)则按其引用传递.

所以是的,具体的对象通过引用传递下来.


演示:

在这个演示中,我们有两个组件,一个父组件和一个子组件.孩子有两个道具,一个是整数1,另一个是对象a: "foo".

片刻后,从父我们改变从整数值1,以2和从对象a: "foo"a: "bar".之后,我们从子组件中记录这些道具的值.

输出仍然1是整数(没有改变 - 通过值传递),但a: "bar"对于对象(已更改! - 通过引用传递).

const Parent = () => { 
  let myInt = 1;
  let myObj = {a: "foo"};
  setTimeout(function(){
    myInt = 2;
    myObj.a = "bar";
  }, 500);
 
  return <Child myInt={myInt} myObj={myObj} />;
}

const Child = ({myInt, myObj}) => {
  setTimeout(function(){
    console.log(myInt);
    console.log(myObj);
  }, 1000);
  
  return (
    <div>
      <p>{myInt}</p>
      <p>{JSON.stringify(myObj)}</p>
    </div>
  );
}
 
ReactDOM.render(<Parent />, document.getElementById("app"));
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Run Code Online (Sandbox Code Playgroud)