将组件作为道具传递的更好方法是什么?

时间:2019-12-09 11:22:08

标签: javascript reactjs

在props中传递组件的更好方法是什么?以及将其称为“组件”还是“函数”会更好。还是没有区别?

Int
const HeaderComponet = props => {
  return <div style={styles.header}>Header</div>;
};

const renderCardBody = props => {
  return <div style={styles.body}>Body</div>;
};

function App() {
  return (
    <Card HeaderComponet={HeaderComponet} renderCardBody={renderCardBody} />
  );
}

codesandbox enter image description here

2 个答案:

答案 0 :(得分:5)

我只是将其呈现为子组件

<Card>
  <HeaderComponent {...props}/>
  <RenderCardBody {...props}/>
</Card>

答案 1 :(得分:4)

  

如何更好地将其称为“组件”或“函数”

理论上,两者是相同的。我们编写的JSX被转换为基于函数的JS,并以此方式使用。

示例:

该使用哪个?

  • 功能:是否涉及处理。根据1个状态说,它应该显示横幅。在另一种形式上。是的,逻辑可以按需移至另一个组件,但是,如果一个组件需要智能并根据状态进行处理,则应在一个函数中进行处理
  • 组件:如果直接消耗。就像包装多个组件以创建结构的表单组件一样。

  

在props中传递组件的更好方法是什么?

在我的POV中,不应将组件作为道具传递。组件应该知道它的消耗量。仍然,如果您想拥有动态组件,我将按照以下方式进行。

  • 创建可能使用的组件列表,并基于该列表创建地图。
  • 创建props getter函数,以便您可以动态使用它。
  • 现在基于道具,获取组件和道具,并进行渲染。

示例:

在props中传递组件的更好方法是什么?

注意:Tile组件仅用于演示,因此非常基础。实际上,它们可能更复杂

const DefaultTile = (props) => Array.from({ length: props.count }, (_, i) => <div className='tile medium-tile' key={i}>Tile</div>) 

const LargeTile = (props) => Array.from({ length: props.count }, (_, i) => <div className='tile large-tile' key={i}>Tile</div>) 

const SmallTile = (props) => Array.from({ length: props.count }, (_, i) => <div className='tile small-tile' key={i}>Tile</div>) 

const componentMap = {
  large: LargeTile,
  medium: DefaultTile,
  small: SmallTile
}
  
const renderPropMap = {
  large: (props) => ({ count: props.count, showExtraInfo: props.info }),
  medium: (props) => ({ count: props.count }),
  small: (props) => ({ count: props.count, onHover: props.onHover })
}  

const App = (props) => {
  const Comp = componentMap[props.size];
  const childProps = renderPropMap[props.size](props)
  return <Comp { ...childProps } />
}

ReactDOM.render(<App size='medium' />, document.querySelector("#app"))
.tile {
  border: 1px solid gray;
  display: inline-block;
  margin: 4px;
}

.small-tile {
  width: 50px;
  height: 50px;
}

.medium-tile {
  width: 100px;
  height: 100px;
}

.large-tile {
  width: 200px;
  height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="app"></div>