ReactElement作为属性传递有什么区别:

<RenderParam ReactElement={<Counter />} />

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


First case

并传递一个返回ReactElement的函数:

<RenderParam ReactElement={instantiatedCounter} />

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


Second case

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


每次父反应元素更新时,对于第二种情况,都会执行Counter的安装周期:

ReactElement changed (at RenderParam lifecycle)
component did mount (at Counter)

同样,第二种情况会在每次父组件渲染时丢失其状态。


我看不出它们之间有什么区别。为什么第一种情况能够保持其状态?

最佳答案

第一个示例将静态JSX元素<Counter />作为RenderParam属性传递。第二个示例使用函数instantiatedCounter,该函数允许返回更动态的JSX元素,通常称为Render props

在第二种情况下,您会丢失状态,因为React每次都会将ReactElement道具视为一个新定义的组件,将旧组件卸载,然后在每个渲染周期将其重新安装。您要做的是调用ReactElement属性以检索JSX元素作为返回值:

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


您也可以使用JSX语法<div><ReactElement /></div>对其进行定义。但是,请确保instantiatedCounter是静态函数,并且不会在每个渲染器上都重新创建它,所以对象引用保持不变:

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} />
}

07-26 01:03