如果要通过组件属性将对象传递给子组件,则该对象是否被克隆,还是只是将引用传递给原始对象?
例如在我App.js导入一个JSON对象ENTRY_DATA。然后,我通过道具将该对象传递给我的子组件(或本例中的路由)。我是通过这样做节省了内存,还是就像我要ENTRY_DATA在每个组件上导入一样?
App.js
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);
如果ENTRY_DATA是5kb,那么我将其传递给3个不同的部分,是否意味着我最终获得了20kb的价值,ENTRY_DATA或者它们都引用了一个5kb ENTRY_DATA?
通常,它取决于所述道具的数据类型。基元(例如 整数 或 字符串) 按其值向下传递,而对象数据类型(如 数组) 按其引用向下传递。
是的, 对象 是通过引用传递的。
演示:
在此演示中,我们有两个部分,一个父母和一个孩子。子代有两个道具,一个是整数1,另一个是的对象a: "foo"。
1
a: "foo"
片刻之后,我们从父级将整数值从更改1为2并将对象从a: "foo"更改为a: "bar"。之后,我们从子组件中记录这些道具的值。 注意: 这是一个无状态组件,因此我们不使用任何状态。我们直接更改值,所以React永远不会 “知道” 这一更改! (ssh,不要告诉React!)
2
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")); <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>