优雅的方式来使道具的类型无关

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

考虑到我有,它接受一个道具,这将是为这两种工作的最简单,最优雅的方式一个组件:

<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>
        )
    }
}
reactjs
1个回答
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
};

如果你想让它都做,你可以把一个||条件有了它,如果定义的消息。该消息将被默认显示,如果它存在,否则孩子们函数将被执行:

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'>
© www.soinside.com 2019 - 2024. All rights reserved.