我如何深克隆具有react.element的对象

问题描述 投票:1回答:1

深度克隆具有react元素的对象会破坏该元素,您将无法再渲染该元素,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;

我还尝试了其他几个深度克隆库,但在我看来它们都不起作用!所以您知道一个这样做的库吗?或者也许我可以通过做一些事情来修复当前的克隆库?还是我可以写自己的深克隆内容,对此有何建议?到目前为止我尝试过的是:1-使用import CloneDeep from "clone-deep";将导致objects are not valid as a react child错误2-使用import cloneDeep from "lodash.clonedeep";,该错误与先前的库没有相同的错误,但是会引发infinity loop, Max Stack错误!谢谢。

javascript reactjs deep-copy
1个回答
0
投票

我去了github clone-deep复制了他们的代码并进行了一些更改1-首先我使用React.isValidElement检查该值是否为react元素2-感谢@warmachine我使用React.cloneElement如果对象是用于克隆对象的react元素,否则,我会执行库始终执行的操作

在这里您可以看到完整的代码:

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.