我如何深度克隆具有 react.element 的对象
How can i deepclone an object which has a react.element
深度克隆具有反应元素的对象会破坏该元素,您将无法再渲染该元素,
Here is an example showing this issue
import React from "react";
import "./styles.css";
import Demo from "./Demo";
export default function App() {
const test = <div>I'm a react element</div>;
console.log("test", test);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Demo obj={{ element: test }} />
</div>
);
}
//Demo.js
import React from "react";
// import cloneDeep from "lodash.clonedeep";
import CloneDeep from "clone-deep";
const Demo = ({ obj }) => {
const newProps = CloneDeep(obj);
console.log(newProps.element);
// console.log("Demo element", newProps.element);
return (
<div>
I'm Demo Component
{newProps.element}
</div>
);
};
export default Demo;
我还尝试了其他几个深度克隆库,但其中 none 似乎适用于我的情况!所以你知道有哪个库可以做到这一点吗?或者我可以通过做些什么来修复当前的克隆库?或者也许我可以编写自己的深度克隆,有什么建议吗?
到目前为止我尝试了什么:
1- 使用 import CloneDeep from "clone-deep";
会导致 objects are not valid as a react child
错误
2-使用 import cloneDeep from "lodash.clonedeep";
与之前的库没有相同的错误,但抛出 infinity loop, Max Stack
错误!
谢谢。
我去了 github
clone-deep
复制了他们的代码并做了一些更改
1-首先我使用 React.isValidElement
检查该值是否是反应元素
2-感谢@warmachine 我使用 React.cloneElement
如果对象是一个反应元素来克隆对象,如果不是,我会做图书馆一直做的事
这里可以看到完整的代码:
import React from "react";
const clone = require("shallow-clone");
const typeOf = require("kind-of");
const isPlainObject = require("is-plain-object");
export function cloneDeep(val, instanceClone) {
if (React.isValidElement(val)) {
return React.cloneElement(val);
} else {
const valueType = typeOf(val);
switch (valueType) {
case "object":
return cloneObjectDeep(val, instanceClone);
case "array":
return cloneArrayDeep(val, instanceClone);
default: {
return clone(val);
}
}
}
}
function cloneObjectDeep(val, instanceClone) {
if (typeof instanceClone === "function") {
return instanceClone(val);
}
if (instanceClone || isPlainObject(val)) {
const res = new val.constructor();
for (let key in val) {
res[key] = cloneDeep(val[key], instanceClone);
}
return res;
}
return val;
}
function cloneArrayDeep(val, instanceClone) {
const res = new val.constructor(val.length);
for (let i = 0; i < val.length; i++) {
res[i] = cloneDeep(val[i], instanceClone);
}
return res;
}
这当然是一个临时解决方案,直到我找到更好的解决方案或者希望 git 集线器所有者反映我发布的问题
深度克隆具有反应元素的对象会破坏该元素,您将无法再渲染该元素,
Here is an example showing this issue
import React from "react";
import "./styles.css";
import Demo from "./Demo";
export default function App() {
const test = <div>I'm a react element</div>;
console.log("test", test);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Demo obj={{ element: test }} />
</div>
);
}
//Demo.js
import React from "react";
// import cloneDeep from "lodash.clonedeep";
import CloneDeep from "clone-deep";
const Demo = ({ obj }) => {
const newProps = CloneDeep(obj);
console.log(newProps.element);
// console.log("Demo element", newProps.element);
return (
<div>
I'm Demo Component
{newProps.element}
</div>
);
};
export default Demo;
我还尝试了其他几个深度克隆库,但其中 none 似乎适用于我的情况!所以你知道有哪个库可以做到这一点吗?或者我可以通过做些什么来修复当前的克隆库?或者也许我可以编写自己的深度克隆,有什么建议吗?
到目前为止我尝试了什么:
1- 使用 import CloneDeep from "clone-deep";
会导致 objects are not valid as a react child
错误
2-使用 import cloneDeep from "lodash.clonedeep";
与之前的库没有相同的错误,但抛出 infinity loop, Max Stack
错误!
谢谢。
我去了 github
clone-deep
复制了他们的代码并做了一些更改
1-首先我使用 React.isValidElement
检查该值是否是反应元素
2-感谢@warmachine 我使用 React.cloneElement
如果对象是一个反应元素来克隆对象,如果不是,我会做图书馆一直做的事
这里可以看到完整的代码:
import React from "react";
const clone = require("shallow-clone");
const typeOf = require("kind-of");
const isPlainObject = require("is-plain-object");
export function cloneDeep(val, instanceClone) {
if (React.isValidElement(val)) {
return React.cloneElement(val);
} else {
const valueType = typeOf(val);
switch (valueType) {
case "object":
return cloneObjectDeep(val, instanceClone);
case "array":
return cloneArrayDeep(val, instanceClone);
default: {
return clone(val);
}
}
}
}
function cloneObjectDeep(val, instanceClone) {
if (typeof instanceClone === "function") {
return instanceClone(val);
}
if (instanceClone || isPlainObject(val)) {
const res = new val.constructor();
for (let key in val) {
res[key] = cloneDeep(val[key], instanceClone);
}
return res;
}
return val;
}
function cloneArrayDeep(val, instanceClone) {
const res = new val.constructor(val.length);
for (let i = 0; i < val.length; i++) {
res[i] = cloneDeep(val[i], instanceClone);
}
return res;
}
这当然是一个临时解决方案,直到我找到更好的解决方案或者希望 git 集线器所有者反映我发布的问题