将渲染逻辑作为组件 prop 与回调函数进行反应

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

假设一个组件需要渲染一堆元素,但渲染必须是可定制的,因为这个组件会在很多地方重复使用。可以把它想象成一个需要渲染事件的日历组件,但事件渲染逻辑应该可以通过日历组件的 props 来控制。

到目前为止,我发现了两种方法可以做到这一点,我不确定哪种方法是正确的,哪种方法是错误的,如果一种方法与另一种方法相比有缺点

1-传递执行渲染的回调

type MainProps = {
   renderStuff: (stuff) => void;
};

function MainComponent(props: MainProps){
   const matchingStuff = [1, 2, 3...]

   return (
     <ul>
       {matchingStuff.map(stuff => <li>{renderStuff(stuff)}</li>)}
     </ul>
   );
}

2- 将组件定义作为 prop 传递:

type StuffProps = {
  stuff: number;
}

type MainProps = {
  renderStuff: FC<StuffProps>;
};

function MainComponent(props: MainProps){
  const matchingStuff = [1, 2, 3...]

  return (
    <ul>
      {matchingStuff.map(stuff => <props.renderStuff stuff={stuff} />)}
    </ul>
  );
}

function Stuff(props: StuffProps){
  return <li>{props.stuff}</li>
}

(注意

renderStuff
的类型差异)

javascript reactjs rendering react-props
1个回答
0
投票

我不知道什么是正确的和错误的方式

不,没有正确或错误的方式,两者都有效(尽管不是以相同的方式 - 见下文),并且是各种高质量反应库中存在的模式。

一些React库实际上同时使用了两者:https://v5.reactrouter.com/web/api/Route

这只是呈现 API 的一种方式。

在某些情况下,您会发现无法使用其中一种,或者其中一种比另一种性能更高。但当你看到这些情况时,你通常就会知道它们。

如果您传递内联函数并将其呈现为组件,则会出现最大的问题,如下所示:

const MyParent = () => <MyChild Component={({prop}) => <>Some Stuff - {prop}</>}/>

const MyChild = ({Component}) => <Component prop={"Render me!"}/>

在我发布的上面的示例中,这是无关紧要的,因为内联函数中没有状态。如果有状态,您会看到每次渲染

MyParent
时,状态都会在
MyChild
中重置,因为它每次都是一个新组件(内联函数)。

在上面的示例中,您可以在渲染函数外部声明组件并将其作为 prop 传递,如下所示:

const MyParentRenderComponent = ({prop}) => <>Some Stuff - {prop}</>

const MyParent = () => <MyChild Component={MyParentRenderComponent}/>

这是 React 中的标准规则:不要在渲染函数(或功能组件的主体)内声明组件,因此它并不是这种情况所独有的。

© www.soinside.com 2019 - 2024. All rights reserved.