考虑到我有一个可以接受一个道具的组件,这两个组件最简单,最优雅的工作方式是什么?
<MessageBlock message="Some message goes here" />
和
<MessageBlock message={() => (
<>
Some message <strong>goes</strong> here
</>
} />
首先想到的是使用typeof
检查道具类型,并根据如下所示渲染道具:
class MessageBlock extends React.Component {
render() {
const { message: Message } = this.props;
return (
<div className="message-block">
{typeof Message === "function" ? (
<Message />
) : (
<>
{message}
</>
)}
</div>
)
}
}
答案 0 :(得分:1)
这取决于您的组件应该能够做什么。
如果您希望组件能够显示其中的任何内容,我建议使用其children
道具作为渲染功能:
const MessageBlock = props => (
<div className={'add the stuff you want to wrap'}>
{props.children()}
</div>
)
const App = props => (
<React.Fragment>
<MessageBlock>
{() =>
<React.Fragment>
Some message <strong>goes</strong> here
</React.Fragment>
}
</MessageBlock>
<MessageBlock>
{() => <p>Another message</p>}
</MessageBlock>
</React.Fragment>
)
ReactDOM.render(<App/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<div id='root'>
但是,如果您希望它不显示字符串,则将propTypes
与您建议的第一个解决方案一起使用:
MessageBlock.propTypes = {
message: PropTypes.string
};
如果您希望它同时执行,则可以定义一个||
条件(如果已定义消息)。如果存在该消息,将默认显示该消息,否则将执行children函数:
const MessageBlock = ({ children, message }) => (
<div className={'add the stuff you want to wrap'}>
{message || children()}
</div>
)
/*MessageBlock.propTypes = { //Proptypes are undefined in SO snippets :(
message: PropTypes.string
};*/
const App = props => (
<React.Fragment>
<MessageBlock>
{() =>
<React.Fragment>
Some message <strong>goes</strong> here
</React.Fragment>
}
</MessageBlock>
<MessageBlock message={'A string message'} />
</React.Fragment>
)
ReactDOM.render(<App/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<div id='root'>