gpt4 book ai didi

javascript - 如果父组件更改,防止子组件卸载和重新安装

转载 作者:行者123 更新时间:2023-12-04 04:25:46 26 4
gpt4 key购买 nike

问题:

在下面的代码中,当 Toggle ParentA/B单击按钮,<Child />组件将被卸载并再次重新安装,但实际上只有 Parent组件改变。

如何预防 Child在这种情况下卸载和重新安装?

import React, { useState } from "react"

const App = () => {
const [a, setA] = useState(true)
return (
<div>
<button onClick={() => setA(!a)}>Toggle ParentA/B</button>
{a ? <ParentA><Child /></ParentA> : <ParentB><Child /></ParentB>}
</div>
)
}
const ParentA = ({ children }) => <div>parentA{children}</div>
const ParentB = ({ children }) => <div>parentB{children}</div>

class Child extends React.Component {
componentDidMount() {
console.log('child did mount')
}

componentWillUnmount() {
console.log('child will unmount')

}

render() {
return (
<div>child</div>
)
}

}

export default App

回复可能的答案:

Why not just let the Child component remount since it's only a <div> element?



通常,如果 Child组件渲染成本低。但是,就我而言, Child组件需要很长时间才能安装,所以每次 Parent 时我都无法重新安装组件变化。

You could pass the parentA or parentB string as props to a generic Parent component.


const App = () => {
const [a, setA] = useState(true)
return (
<div>
<button onClick={() => setA(!a)}>Toggle ParentA/B</button>
<ParentGeneric content={a? 'parentA': 'parentB'}><Child /></ParentGeneric>
</div>
)
}
const ParentGeneric = ({children, content}) => <div>{content}{children}</div>

class Child extends React.Component {
...
}

这会奏效。不幸的是,这限制了我的 Parent组件的 JSX 结构相同。换句话说,如果我的 ParentAParentB的 JSX 结构不同,那么我不确定如何将差异作为 Prop 传递。

例如:
const ParentA = ({ children }) => <div><div><h1>parentA{children}</h1></div></div>
const ParentB = ({ children }) => <div>parentB{children}</div>

如果 parentA 和 parentB 这样定义,是否仍然可以将这两个组件抽象为 ParentGeneric组件和简单地传递 ParentA 之间的结构差异和 ParentB作为 Prop ?

最佳答案

-- 编辑 --
看来我的以下解决方案具有误导性。我现在同意此线程中的其他人的意见,即无法实现问题中所要求的行为。我对原始答案所做的只是阻止挂载/卸载运行。尽管如此,每次更改较高的布局组件时,父组件的全部内容都会被丢弃并从头开始重新渲染。
-- 编辑结束 --
有一种方法!
确实,React 的 reconciliation algorithm将始终挂载和卸载已更换其 parent 的子代(不同的父代类型会导致从更改的父代开始重新安装整个家庭分支)。
但是,您仍然可以将“子”组件显示为某些父布局组件的子组件,而不是在父类型更改时挂载/卸载。你只需要改变组件树的顺序,利用渲染 Prop 模式:

  • 首先渲染子(重)组件。
  • Child 获得一个组件 prop,它将成为父布局组件。
  • 然后子级从 Prop 渲染其父级围绕自身 , 将自己设置为其 parent 的 child 。
  • Parent 是布局组件,无论您在哪里选择,都可以将其渲染为子组件!

  • 示例,根据您提供的代码:
    import { useState, Component } from "react";

    const App = () => {
    const [a, setA] = useState(true);
    return (
    <div>
    <button onClick={() => setA((prev) => !prev)}>Toggle ParentA/B</button>
    <Child layout={a ? ParentA : ParentB} />
    </div>
    );
    };
    const ParentA = ({ children }) => <div>parentA{children}</div>;
    const ParentB = ({ children }) => <div>parentB{children}</div>;

    class Child extends Component {
    componentDidMount() {
    console.log("child did mount");
    }

    componentWillUnmount() {
    console.log("child will unmount");
    }

    render() {
    return (
    <this.props.layout>
    <div>child</div>
    </this.props.layout>
    );
    }
    }

    export default App;
    工作代码沙盒: https://codesandbox.io/s/change-parent-no-unmounted-child-nnek0?file=/src/App.js
    检查控制台,它可以工作,并且是一种可以接受的做法。

    关于javascript - 如果父组件更改,防止子组件卸载和重新安装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57457445/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com