代码之家  ›  专栏  ›  技术社区  ›  Rashomon

作为属性传递ReactElement和返回ReactElement的函数之间的区别

  •  0
  • Rashomon  · 技术社区  · 5 年前

    通过考试有什么区别 ReactElement 作为一种财产:

    First case

    <RenderParam ReactElement={<Counter />} />
    
    function RenderParam({ ReactElement }) {
      return <div>{ReactElement}</div>;
    }
    

    传递一个返回 反应元素 :

    Second case

    const instantiatedCounter = () => <Counter />; 
    
    <RenderParam ReactElement={instantiatedCounter} />
    
    function RenderParam({ ReactElement }) {
      return <div> <ReactElement /> </div> 
    }
    

    我发现生命周期中存在差异:

    • 每次父react元素更新时 Counter 针对第二种情况执行:
    ReactElement changed (at RenderParam lifecycle)
    component did mount (at Counter)
    
    • 此外,第二种情况在父组件每次渲染时都会丢失其状态。

    我看不出他们之间有什么区别。为什么第一个病例能够保持其状态?

    1 回复  |  直到 4 年前
        1
  •  2
  •   ford04    5 年前

    第一个示例传递一个静态JSX元素 <Counter /> RenderParam 道具第二个例子使用了一个函数 instantiatedCounter ,它允许返回更动态的JSX元素,通常称为 Render props .

    在第二种情况下,你会失去状态,因为React会处理 ReactElement 每次将道具作为新定义的组件,卸载旧组件并在每个渲染周期中再次装载。你想做的是 呼叫 这个 反应元素 prop将JSX元素作为返回值检索:

    function RenderParam({ ReactElement }) {
      return <div>{ReactElement()}</div>; 
      // not: return <div><ReactElement /></div>
    }
    

    你也可以用JSX语法来定义它 <div><ReactElement /></div> .但要确保, 实例化计数器 是一个静态函数,不会在每次渲染时重新创建,因此对象引用保持不变:

    const instantiatedCounter = () => <Counter />; 
    // make it static in some way, so object reference doesn't change
    
    export default function App() {
      // .. and remove instantiatedCounter here
      return <RenderParam ReactElement={instantiatedCounter} />
    }
    
        2
  •  2
  •   fadeys.work    5 年前

    这其实很简单,真正的问题是渲染本身的时间。

    让我们从第二种情况开始,这实际上是一种叫做Render Props的设计模式,您可以在这里阅读: https://reactjs.org/docs/render-props.html 在本例中,prop包含一个返回React元素的函数,这意味着只有在调用该函数时才会对其求值,因此它并不总是像第一个例子中那样“活动”。

    第一种情况:当您将道具绑定到一个元素时,它会在父元素创建时得到评估。这意味着,只要父元素是“活动的”,prop元素就将是活动的。