diff --git a/README.md b/README.md index bc8ad3f..daddb1d 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,49 @@ We can add an `Else` component as the last child of `Whether` to get 2 branches. ### More branches +#### simple condition branches: perform switch and case logic + +```jsx +let testValue = 4; + +... +render() { + return ( + + + negative review + + + medium review + + + good review + + + ); +} +``` + +```jsx +let testValue = 4; + +... +render() { + switch (testValue) { + case 1: + return 'negative review'; + case 2: + case 3: + return 'medium review'; + default: + return 'good review'; + } +} + +``` + +#### complex condition branches + For more complex condition branches, `context` prop allows `Whether` to manage a condition context and perform more branches, you can use `Match` and its `selector` prop to create a branch. ```jsx diff --git a/src/Case.js b/src/Case.js new file mode 100644 index 0000000..adfac13 --- /dev/null +++ b/src/Case.js @@ -0,0 +1,24 @@ +/** + * @file 空组件,用于给`Switch`使用 + * @author daxuewen + */ + +import PropTypes from 'prop-types'; + +/* istanbul ignore next line */ +const Case = () => null; + +Case.displayName = 'Case'; + +Case.propTypes = { + children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired, + value: PropTypes.any, + values: PropTypes.array +}; + +Case.defaultProps = { + value: undefined, + values: [] +}; + +export default Case; diff --git a/src/Default.js b/src/Default.js new file mode 100644 index 0000000..222a463 --- /dev/null +++ b/src/Default.js @@ -0,0 +1,17 @@ +/** + * @file 空组件,用于给`Switch`使用 + * @author daxuewen + */ + +import PropTypes from 'prop-types'; + +/* istanbul ignore next line */ +const Default = () => null; + +Default.displayName = 'Default'; + +Default.propTypes = { + children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired +}; + +export default Default; diff --git a/src/Switch.js b/src/Switch.js new file mode 100644 index 0000000..47b1679 --- /dev/null +++ b/src/Switch.js @@ -0,0 +1,43 @@ +/** + * @file 模拟`switch case`语句 + * @author daxuewen + */ + +import {Children} from 'react'; +import PropTypes from 'prop-types'; +import Case from './Case'; +import Default from './Default'; + +const renderElement = element => (typeof element === 'function' ? element() : element); + +const Switch = ({value, children}) => { + const childrenCount = Children.count(children); + const lastChild = childrenCount === 1 ? children : children[children.length - 1]; + const defaultChild = lastChild.type === Default ? lastChild : null; + + const cases = children.filter(child => child.type === Case); + const matchedCase = cases.find(({props}) => { + if (props.values && props.values.length > 0) { + return props.values.some(item => item === value); + } + + return props.value === value; + }); + + if (matchedCase) { + return renderElement(matchedCase.props.children); + } + + if (defaultChild) { + return renderElement(defaultChild.props.children); + } + + return null; +}; + +Switch.propTypes = { + value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]).isRequired, + children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired +}; + +export default Switch;