Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在React组件中将字符串化对象作为prop传递比普通JavaScript对象好吗?_Javascript_Reactjs - Fatal编程技术网

在React组件中将字符串化对象作为prop传递比普通JavaScript对象好吗?

在React组件中将字符串化对象作为prop传递比普通JavaScript对象好吗?,javascript,reactjs,Javascript,Reactjs,只是我担心,我知道当道具改变时,组件将被重新渲染。 React无法对传递给道具的新旧对象执行深度比较 因此: {key:'value'}和{key:'value'}始终不同,并导致重新渲染 将对象传递给以下道具如何: 它是一个字符串,因此React可以有效地比较新旧版本?字符串化版本会增加额外的计算开销,因此如果您想大量使用它,可能会降低网站速度 您可以使用this.forceUpdate()手动更新视图,但如果您使用诸如redux之类的工具,则大多数时候不需要这样做。一些示例.jsx文件将有

只是我担心,我知道当道具改变时,组件将被重新渲染。 React无法对传递给道具的新旧对象执行深度比较 因此:

{key:'value'}
{key:'value'}
始终不同,并导致重新渲染

将对象传递给以下道具如何:


它是一个字符串,因此React可以有效地比较新旧版本?

字符串化版本会增加额外的计算开销,因此如果您想大量使用它,可能会降低网站速度


您可以使用
this.forceUpdate()
手动更新视图,但如果您使用诸如redux之类的工具,则大多数时候不需要这样做。一些示例
.jsx
文件将有助于确定如何避免像将内容转换为字符串这样的黑客行为。

字符串是一种基本类型,因此
“a”==“a”//true
如果通过
JSON.stringify()
将它们转换为字符串,则只要对象结构保持不变,就不会触发重新渲染。顺便说一句,这是一个反模式-你不应该比较stringify版本。(credit@DennisVash)

但对象是引用类型;因此
{}=={}//false
但是如果存储对象引用并将其传递给props,它在渲染中不会更改,也不会每次触发重新渲染;这里是将obj参考保持在局部状态的功能组件中的示例

//!! it can be placed outside the component and wont change in recurring renders; 
//!! it will work; but definitely not recommended;
// let obj = { key: 'value'} 

function FancyComponent() {
  const [obj, setObj] = useState({ key: 'value'});

  // optionally you may store it in ref, in some special use-cases
  // const ref = useRef({ key: "value" });

  render(){
    // let obj = { key: 'value'} //!! no it won't work here credits to @EmileBergeron
    return <>
      <Component smth={obj}/>
    </>
  }
}

@长qd是的,确切地说,我们称之为
浅层比较
;谷歌表示,为了进一步阅读,这个例子具有误导性。将对象存储在局部变量中与直接传递对象是一样的,这有利于比较。任何未在每个渲染周期实例化的对象都将使用相同的对象引用Redux、context、
useRef
useState
useReducer
usemo
、模块范围变量,甚至全局变量(但不要),等等。@EmileBergeron用状态钩子修复了这个例子@longlqd意味着我们试图将对象引用保存在变量中,并在以后重用它,但我们只是每次创建新变量并将新变量传递给props,这意味着在新变量中有一个新引用,因此“无用”;如果我们不衡量,你所指出的是很难知道的。但这仍然是我们需要关注的事情。谢谢。答案是否定的,你应该传递JS对象。如果你想要一个具体的解释,你应该给出一个实际的例子,这是一个反模式,你应该修正组件的逻辑/使用记忆。老实说,它只是出现在我的脑海中,我没有实际的例子。但是如果它是ant模式,我认为它应该对此有某种共同的解释。React的最佳实践是只传递相关数据作为道具,而不是整个对象或状态。大多数情况下,作为prop值的整个对象来自以某种状态(本地、上下文、redux等)存储的某些数据,并且它不会在每个渲染周期重新实例化,它只是传递的同一个对象引用。正如Dennis Vash所说,内存化是计算对象/数组的一种解决方案,但首先,在进行任何不必要的内存化之前,先测量性能,因为它最终只会使应用程序逻辑复杂化,性能改善也很小。