ConfigProvider 全局配置 Next 组件

如果项目中使用的是 0.x 版本的基础组件(@icedesign/base, @ali/ice, @alife/next),请在左侧导航顶部切换组件版本。

安装方法

  1. 在命令行中执行以下命令npm install @alifd/next@latest -S

开发指南

何时使用

  • 修改组件类名前缀,Next 组件类名的默认前缀都是 'next-',如 'next-btn',你可能在以下两种情况下想改变这个默认前缀:

    • 自定义组件品牌,如 'my-btn','my-select'

    • 一个页面中同时引入两个主题,防止相同类名样式互相覆盖

  • 实现多语言文案切换

  • 开启 Pure Render 模式,提高性能,注意同时可能会带来副作用

基本使用

指定多语言文案

通过 <ConfigProvider locale={localeObj}> 传入语言包,以支持多语言。目前 Fusion 内置的 locale 库支持中英繁日四种语言,覆盖各组件的简单词汇,例如:确定、取消、展开、收起、下一页等, 简单词汇映射表可参考 https://unpkg.com/@alifd/next/lib/locale/(ConfigProvider 提供简单组件简单词汇国际化能力,由于日期时间的国际化较为特殊,例如中国的日历是从周一到周日,美国的日历是从周日到周六等,时间相关的组件如DatePicker等需要国际化,请查看相应组件文档。)

可通过两种方式设置多语言文案,两种方式接收的对象格式略有不同:

  • 1.设置组件自身 locale 属性
  1. {
  2. key1: value1,
  3. key2: value2
  4. }
  • 2.ConfigProvider 的 locale 属性 (推荐)
  1. {
  2. component1: {
  3. key1: value1,
  4. key2: value2
  5. },
  6. component2: {
  7. key1: value1,
  8. key2: value2
  9. }
  10. }

优先级顺序为: 组件自身 locale > 最近 ConfigProvider 的 locale > 更远父级 ConfigProvider 的 locale

(注: 由于Dialog.show() Message.show() 等函数式方法的特殊性,他们的将默认读取页面上的root context。当页面上有多个包含<ConfigProvider/>ReactDOM.render()方法调用时,由第一个渲染的决定root context)

  1. import { ConfigProvider, DatePicker } from '@alifd/next';
  2. const localeDatePicker = {
  3. placeholder: 'localeDatePicker placeholder'
  4. };
  5. const localeGlobal = {
  6. DatePicker: {
  7. placeholder: 'localeGlobal placeholder'
  8. }
  9. };
  10. class App extends React.Component {
  11. render() {
  12. return (
  13. <div>
  14. <ConfigProvider locale={localeGlobal}>
  15. <DatePicker /> should be 'localeGlobal placeholder'
  16. </ConfigProvider>
  17. <br />
  18. <br />
  19. <ConfigProvider locale={localeGlobal}>
  20. <DatePicker locale={localeDatePicker} /> should be 'localeDatePicker placeholder'
  21. </ConfigProvider>
  22. </div>
  23. );
  24. }
  25. }

根据引入组件库方式的不同(CDN直接引用、作为依赖引用),使用语言包的方式略有差异,具体见如下代码:

  1. import { ConfigProvider, DatePicker } from '@alifd/next';
  2. import enUS from '@alifd/next/lib/locale/en-us';
  3. // import zhCN from '@alifd/next/lib/locale/zh-cn';
  4. // import zhTW from '@alifd/next/lib/locale/zh-tw';
  5. // import jaJP from '@alifd/next/lib/locale/ja-jp';
  6. // 如果应用中直接引入的是 cdn 上的 next-with-locales.js 文件
  7. // 需要按照下面的方式引入国际化文案文件
  8. // const { ConfigProvider, DatePicker, locales } = window.Next;
  9. // const enUS = locales['en-us'];
  10. class App extends React.Component {
  11. render() {
  12. return (
  13. <ConfigProvider locale={enUS}>
  14. <DatePicker />
  15. </ConfigProvider>
  16. );
  17. }
  18. }

如果内置的 locale 库不满足你的需求(比如想支持法语、德语、西班牙语),你也可以参考 https://unpkg.com/@alifd/next/lib/locale/ 来自定义语言包,按照如下格式传入给 locale 即可:

  1. {
  2. DatePicker: {
  3. datePlaceholder: 'Select date',
  4. monthPlaceholder: 'Select month',
  5. yearPlaceholder: 'Select year',
  6. rangeStartPlaceholder: 'Start date',
  7. rangeEndPlaceholder: 'End date',
  8. ok: 'OK',
  9. clear: 'Clear'
  10. },
  11. Dialog: {
  12. // ...
  13. },
  14. // ...
  15. }

修改组件类名前缀

  • 为你的应用包裹 ConfigProvider,并设置相应的 prefix

entry.jsx

  1. class App extends React.Component {
  2. render() {
  3. return (
  4. <ConfigProvider prefix="my-">
  5. <div>
  6. <Input />
  7. <Button>Submit</Button>
  8. </div>
  9. </ConfigProvider>
  10. );
  11. }
  12. }
  • scss 入口文件中在引入主题 scss 文件前,设置相应的 $css-prefix

entry.scss

  1. $css-prefix: "my-";
  2. @import "~@alifd/theme-xxx/index.scss";

开启 Pure Render

  1. import { ConfigProvider, DatePicker } from '@alifd/next';
  2. class App extends React.Component {
  3. render() {
  4. return (
  5. <ConfigProvider pure>
  6. <DatePicker />
  7. </ConfigProvider>
  8. );
  9. }
  10. }

如何让组件支持 ConfigProvider ?

  1. import { ConfigProvider } from '@alifd/next';
  2. import locale from './locale';
  3. const { config } = ConfigProvider;
  4. class Component extends React.Component {
  5. static propTypes = {
  6. prefix: PropTypes.string,
  7. locale: PropTypes.object,
  8. pure: PropTypes.bool
  9. };
  10. static defaultProps = {
  11. prefix: 'next-',
  12. locale: locale,
  13. pure: false
  14. };
  15. render() {
  16. const { prefix, locale, pure } = this.props;
  17. // ...
  18. }
  19. }
  20. export default config(Component);

API

ConfigProvider

参数说明类型默认值
errorBoundary是否开启错误捕捉 errorBoundary如需自定义参数,请传入对象 对象接受参数列表如下:fallbackUI Function(error?: {}, errorInfo?: {}) => Element 捕获错误后的展示afterCatch Function(error?: {}, errorInfo?: {}) 捕获错误后的行为, 比如埋点上传Boolean/Objectfalse
pure是否开启 Pure Render 模式,会提高性能,但是也会带来副作用Boolean-
warning是否在开发模式下显示组件属性被废弃的 warning 提示Booleantrue
rtl是否开启 rtl 模式Boolean-
children组件树ReactElement-
<!— api-extra-start —>

ConfigProvider.config(Component)

传入组件,生成受 ConfigProvider 控制的 HOC 组件,如果组件没有声明 shouldComponentUpdate 方法,会添加如下 shouldComponentUpdate 方法以支持 ConfigProvider 的 pure 属性

  1. Component.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {
  2. if (this.props.pure) {
  3. return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);
  4. }
  5. return true;
  6. };

ConfigProvider.getContextProps(props, displayName)

传入组件的 props 和 displayName,得到和 childContext 计算过的包含有 preifx/locale/pure 的对象,一般用于通过静态方法生成脱离组件树的组件。

ConfigProvider.getContext()

通过该方法可以获取到 ConfigProvider 的上下文,格式如下。若有多层级 ConfigProvider 嵌套,会返回merge后的结果,关系近的优先。

  1. {
  2. prefix: nextPrefix,
  3. locale: nextLocale,
  4. pure: nextPure,
  5. warning: nextWarning
  6. }

ConfigProvider.initLocales(locales)

配置所有语言包, 可配合 ConfigProvider.setLanguage 方法,确定组件使用的语言包。

  1. ConfigProvider.initLocales({
  2. 'zh-cn': {},
  3. 'en-us': {}
  4. });

ConfigProvider.setLanguage(language)

设置语言,参数 language 需要能在 ConfigProvider.initLocales 方法传入的参数的 key 中找到, 默认为 zh-cn

  1. ConfigProvider.setLanguage('zh-cn');

ConfigProvider.setLocale(locale)

直接设置语言包

  1. // 相当于 同时用ConfigProvider.initLocales 和 ConfigProvider.setLanguage
  2. ConfigProvider.setLocale({
  3. DatePicker: {},
  4. Dialog: {}
  5. });

ConfigProvider.setDirection(dir)

设置组件展示方向,当传入 rtl时,会在组件的根DOM节点加上 dir="rtl",同时组件展示rtl视觉。可用于阿拉伯等阅读顺序从右到左的国家。

  1. ConfigProvider.setDirection('rtl');

ConfigProvider.getLocale()

获取当前的语言包

ConfigProvider.getLanguage()

获取当前设定的语言

ConfigProvider.getDirection()

获取当前设定的方向<!— api-extra-end —>

使用注意

减小应用中 webpack 打包 moment 体积

Next 1.x 中将 moment 作为自己的 peerDependencies 而非 dependencies,所以用户需要自己在应用中引入 moment 的 cdn 文件 moment-with-locales.js 或者本地安装 moment 打包进自己的应用。对于后者,由于 moment 在引入 locale 文件时存在这样的代码:require('./locale/' + name),如果用 webpack 构建,会打包进所有的 locale 文件,增加构建后文件的体积,目前社区比较主流的解决方案有以下两种:

  1. const webpack = require('webpack');
  2. module.exports = {
  3. // ...
  4. plugins: [
  5. // 打包指定需要的语言文件
  6. new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /zh-cn|ja/)
  7. // 只打包有过引用的语言文件,应用中需要添加如:`import 'moment/locale/zh-cn';`
  8. // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  9. ]
  10. };

为自定义组件添加 displayName

ConfigProvider 获取组件对应的多语言文案,是通过组件的 displayName 或者 name 获取的,但是压缩混淆的过程中有可能会修改函数的 name,因此如果想支持在 ConfigProvider 下实现切换多语言切换,请为组件如下手动添加 displayName:

  1. class CustomComponent extends React.Component {
  2. static displayName = 'CustomComponent';
  3. // ...
  4. }

或者使用 babel-plugin-transform-react-es6-displayname 自动在编译期间添加 displayname。

获取 HOC 组件内部组件的引用

由于 HOC 本身的限制,我们不能直接像下面代码那样获取内部组件的引用,从而调用它的一些内部方法:

  1. class App extends React.Component {
  2. componentDidMount() {
  3. // 报错
  4. this.refs.hoc.someMethod();
  5. }
  6. render() {
  7. return <HOC ref="hoc" />;
  8. }
  9. }

为了解决这个问题,我们为调用 config 方法生成的 HOC 组件添加了 getInstance 方法,你可以如下调用:

  1. class App extends React.Component {
  2. componentDidMount() {
  3. this.refs.hoc.getInstance().someMethod();
  4. }
  5. render() {
  6. return <HOC ref="hoc" />;
  7. }
  8. }

代码示例

国际化

展示如何配合 ConfigProvider 实现具有国际化能力的组件。

ConfigProvider 全局配置 Next 组件 - 图1

查看源码在线预览

  1. import { ConfigProvider, Button, Select } from '@alifd/next';
  2. import PropTypes from 'prop-types';
  3. const { config, getContextProps } = ConfigProvider;
  4. const { Option } = Select;
  5. const locales = {
  6. 'zh-cn': {
  7. ClickMe: {
  8. clickMe: '点我!'
  9. },
  10. Toast: {
  11. close: '关闭'
  12. }
  13. },
  14. 'en-us': {
  15. ClickMe: {
  16. clickMe: 'click me!'
  17. },
  18. Toast: {
  19. close: 'close'
  20. }
  21. }
  22. };
  23. class ClickMe extends React.Component {
  24. static propTypes = {
  25. locale: PropTypes.object,
  26. onClick: PropTypes.func
  27. };
  28. static defaultProps = {
  29. locale: locales['zh-cn'].ClickMe,
  30. onClick: () => {}
  31. };
  32. render() {
  33. const { locale, onClick } = this.props;
  34. return (
  35. <Button onClick={onClick}>{locale.clickMe}</Button>
  36. );
  37. }
  38. }
  39. class Toast extends React.Component {
  40. static propTypes = {
  41. locale: PropTypes.object,
  42. afterClose: PropTypes.func
  43. };
  44. static defaultProps = {
  45. locale: locales['zh-cn'].Toast,
  46. afterClose: () => {}
  47. };
  48. constructor(props) {
  49. super(props);
  50. this.state = {
  51. visible: false
  52. };
  53. this.handleClose = this.handleClose.bind(this);
  54. }
  55. handleClose() {
  56. this.setState({
  57. visible: false
  58. });
  59. this.props.afterClose();
  60. }
  61. render() {
  62. return (
  63. <div className="toast">
  64. <Button type="primary" onClick={this.handleClose}>
  65. {this.props.locale.close}
  66. </Button>
  67. </div>
  68. );
  69. }
  70. }
  71. Toast.create = (props = {}) => {
  72. const mountNode = document.createElement('div');
  73. document.body.appendChild(mountNode);
  74. const closeChain = () => {
  75. ReactDOM.unmountComponentAtNode(mountNode);
  76. document.body.removeChild(mountNode);
  77. };
  78. const newLocale = getContextProps(props, 'Toast').locale;
  79. ReactDOM.render(<Toast afterClose={closeChain} locale={newLocale} />, mountNode);
  80. };
  81. const NewClickMe = config(ClickMe);
  82. const NewToast = config(Toast);
  83. class Demo extends React.Component {
  84. constructor(props) {
  85. super(props);
  86. this.state = {
  87. language: 'zh-cn'
  88. };
  89. this.handleClick = this.handleClick.bind(this);
  90. this.handleChangeLanguage = this.handleChangeLanguage.bind(this);
  91. }
  92. handleClick() {
  93. NewToast.create();
  94. }
  95. handleChangeLanguage(language) {
  96. this.setState({
  97. language
  98. });
  99. }
  100. render() {
  101. const { language } = this.state;
  102. return (
  103. <ConfigProvider locale={locales[language]}>
  104. <div>
  105. <div className="select-language">
  106. <Select value={language} onChange={this.handleChangeLanguage}>
  107. <Option value="zh-cn">zh-cn</Option>
  108. <Option value="en-us">en-us</Option>
  109. </Select>
  110. </div>
  111. <NewClickMe onClick={this.handleClick} />
  112. </div>
  113. </ConfigProvider>
  114. );
  115. }
  116. }
  117. ReactDOM.render(<Demo />, mountNode);
  1. .toast {
  2. position: fixed;
  3. top: 0;
  4. right: 0;
  5. bottom: 0;
  6. left: 0;
  7. margin: auto;
  8. width: 200px;
  9. height: 100px;
  10. line-height: 100px;
  11. text-align: center;
  12. background: white;
  13. box-shadow: 3px 3px 5px 0 rgba(0, 0, 0, .32);
  14. }
  15. .toast .next-btn {
  16. margin: auto;
  17. }
  18. .select-language {
  19. margin-bottom: 20px;
  20. }

基本

最简单的用法,展示 ConfigProvider 是如何工作的。

ConfigProvider 全局配置 Next 组件 - 图2

查看源码在线预览

  1. import { ConfigProvider } from '@alifd/next';
  2. import PropTypes from 'prop-types';
  3. const { config } = ConfigProvider;
  4. class Output extends React.Component {
  5. static propTypes = {
  6. prefix: PropTypes.string,
  7. locale: PropTypes.object,
  8. pure: PropTypes.bool
  9. };
  10. static defaultProps = {
  11. prefix: 'next-',
  12. locale: {
  13. hello: '你好'
  14. },
  15. pure: false
  16. };
  17. render() {
  18. const { prefix, locale, pure } = this.props;
  19. return (
  20. <ul>
  21. <li>prefix: {prefix}</li>
  22. <li>locale: {JSON.stringify(locale)}</li>
  23. <li>pure: {pure.toString()}</li>
  24. </ul>
  25. );
  26. }
  27. }
  28. const NewOutput = config(Output);
  29. class Demo extends React.Component {
  30. render() {
  31. return (
  32. <ConfigProvider prefix="custom-" locale={{ Output: { hello: 'hello' } }} pure>
  33. <NewOutput />
  34. </ConfigProvider>
  35. );
  36. }
  37. }
  38. ReactDOM.render(<Demo />, mountNode);

支持国际化的组件

展示目前 Next 组件中支持国际化的组件。

ConfigProvider 全局配置 Next 组件 - 图3

查看源码在线预览

  1. import { ConfigProvider, Button, Radio, Calendar, Card, DatePicker, Dialog, Pagination, TimePicker, Timeline, Transfer, Select, Upload, Table } from '@alifd/next';
  2. import enUS from '@alifd/next/lib/locale/en-us';
  3. import zhCN from '@alifd/next/lib/locale/zh-cn';
  4. // If the application directly imports the next-with-locales.js file from cdn
  5. // it need to import locale file in the following way
  6. // import { locales } from '@alifd/next';
  7. // const enUS = locales['en-us'];
  8. // const zhCN = locales['zh-cn'];
  9. const RangePicker = DatePicker.RangePicker;
  10. const transferDataSource = (() => {
  11. const dataSource = [];
  12. for (let i = 0; i < 10; i++) {
  13. dataSource.push({
  14. label: `content ${i}`,
  15. value: `${i}`,
  16. disabled: i % 4 === 0
  17. });
  18. }
  19. return dataSource;
  20. })();
  21. class Demo extends React.Component {
  22. constructor(props) {
  23. super(props);
  24. this.state = {
  25. lang: 'en-us'
  26. };
  27. this.changeLang = this.changeLang.bind(this);
  28. this.showDialog = this.showDialog.bind(this);
  29. }
  30. changeLang(lang) {
  31. this.setState({
  32. lang
  33. });
  34. }
  35. showDialog() {
  36. Dialog.confirm({
  37. title: 'Confirm',
  38. content: 'Are you sure you want to delete all alert e-mails waiting in queue?'
  39. });
  40. }
  41. render() {
  42. const locale = this.state.lang === 'en-us' ? enUS : zhCN;
  43. return (
  44. <div>
  45. <div className="change-locale">
  46. <span style={{ marginRight: 16 }}>Change locale of components: </span>
  47. <Radio.Group shape="button" size="large" defaultValue="en-us" onChange={this.changeLang}>
  48. <Radio key="en" value="en-us">English</Radio>
  49. <Radio key="cn" value="zh-cn">中文</Radio>
  50. </Radio.Group>
  51. </div>
  52. <ConfigProvider locale={locale}>
  53. <div className="locale-components">
  54. <Button type="primary" onClick={this.showDialog}>Show Dialog</Button>
  55. <Select style={{ width: '150px' }} dataSource={['hello', 'bye']} />
  56. <DatePicker />
  57. <TimePicker />
  58. <RangePicker />
  59. <Calendar style={{ width: '350px', padding: '12px', border: '1px solid #C4C6CF', borderRadius: '3px' }} shape="card" />
  60. <Pagination defaultCurrent={2} />
  61. <Transfer dataSource={transferDataSource} defaultValue={['3']} defaultLeftChecked={['1']} titles={['Source', 'Target']} />
  62. <Table style={{ width: '500px' }} dataSource={[]}>
  63. <Table.Column title="Name" dataIndex="name" filters={[{ label: 'Filter 1', value: '1' }, { label: 'Filter 2', value: '2' }]} />
  64. <Table.Column title="Age" dataIndex="age" />
  65. </Table>
  66. <Card style={{ width: '300px' }} title="Title">
  67. <div style={{ height: '250px', background: '#F7F8FA' }}></div>
  68. </Card>
  69. <Timeline fold={[{foldArea: [1, 2], foldShow: true}]}>
  70. <Timeline.Item title="Signed" content="Signed, sign Alibaba is a small post office, thanks to the use of STO, look forward to once again at your service" time={'2016-06-10 10:30:00'} state="process"/>
  71. <Timeline.Item title="Ship" content="Express has arrived in Hangzhou, Zhejiang Binjiang company" time={'2016-06-10 09:30:00'} />
  72. <Timeline.Item title="Ship" content="Zhejiang Hangzhou Riverside company sent a member for you to send pieces" time={'2016-06-10 09:03:00'} />
  73. <Timeline.Item title="Ship" content="Zhejiang Hangzhou Transshipment Center has been issued" time={'2016-06-10 06:10:00'} />
  74. </Timeline>
  75. <Upload.Dragger style={{ width: '500px' }}
  76. listType="image"
  77. action="https://www.easy-mock.com/mock/5b713974309d0d7d107a74a3/alifd/upload"
  78. accept="image/png, image/jpg, image/jpeg, image/gif, image/bmp" />
  79. </div>
  80. </ConfigProvider>
  81. </div>
  82. );
  83. }
  84. }
  85. ReactDOM.render(<Demo />, mountNode);
  1. .change-locale {
  2. border-bottom: 1px solid #d9d9d9;
  3. padding-bottom: 16px;
  4. }
  5. .locale-components > * {
  6. margin: 16px 0;
  7. display: block;
  8. }

使用 Consumer 组件读取上下文中的数据

使用 <Consumer> 可以方便地读取 <ConfigProvider> 中上下文的数据

ConfigProvider 全局配置 Next 组件 - 图4

查看源码在线预览

  1. import { ConfigProvider } from '@alifd/next';
  2. import PropTypes from 'prop-types';
  3. const localeSettings = {
  4. momentLocale: 'fr-FR',
  5. CustomizedComponent: {
  6. helloWorld: 'hello, world'
  7. }
  8. };
  9. const App = ({ children }) => (
  10. <ConfigProvider
  11. prefix="customized-"
  12. locale={localeSettings}
  13. pure
  14. warning={false}
  15. >
  16. {children}
  17. </ConfigProvider>
  18. );
  19. App.propTypes = {
  20. children: PropTypes.node
  21. };
  22. const Child = () => (
  23. <ConfigProvider.Consumer>
  24. {
  25. context => (
  26. <div className="context-data">
  27. <h3>Context's state</h3>
  28. <pre>{JSON.stringify(context, false, 2)}</pre>
  29. </div>
  30. )
  31. }
  32. </ConfigProvider.Consumer>
  33. );
  34. const Demo = () => (
  35. <App>
  36. <Child />
  37. </App>
  38. );
  39. ReactDOM.render(<Demo />, mountNode);
  1. .context-data {
  2. padding: 0 32px 32px;
  3. border: 3px dashed #aaa;
  4. border-radius: 9px;
  5. }

组件的RTL

组件RTL样式展示(目前部分支持)

ConfigProvider 全局配置 Next 组件 - 图5

查看源码在线预览

  1. import { ConfigProvider, Button, Radio, Menu, Calendar, DatePicker, Dialog, TimePicker, Timeline, Select } from '@alifd/next';
  2. const { SubMenu, Item, Group, Divider } = Menu;
  3. const RangePicker = DatePicker.RangePicker;
  4. // Set global direction to 'rtl'. This affects the whole page
  5. // ConfigProvider.setDirection('rtl');
  6. class Demo extends React.Component {
  7. constructor(props) {
  8. super(props);
  9. this.state = {
  10. dir: 'rtl'
  11. };
  12. this.changeDir = this.changeDir.bind(this);
  13. this.showDialog = this.showDialog.bind(this);
  14. }
  15. changeDir(value) {
  16. this.setState({
  17. dir: value
  18. });
  19. }
  20. showDialog() {
  21. Dialog.confirm({
  22. title: 'Confirm',
  23. content: 'Are you sure you want to delete all alert e-mails waiting in queue?'
  24. });
  25. }
  26. render() {
  27. return (
  28. <div>
  29. <div className="change-rtl">
  30. <span style={{ marginRight: 16 }}>Change direction of components: </span>
  31. <Radio.Group shape="button" size="large" value={this.state.dir} onChange={this.changeDir}>
  32. <Radio key="rtl" value="rtl">RTL</Radio>
  33. <Radio key="ltr" value="ltr">LTR</Radio>
  34. </Radio.Group>
  35. </div>
  36. <br />
  37. <hr />
  38. <ConfigProvider rtl={this.state.dir === 'rtl'}>
  39. <div className="locale-components" dir={this.state.dir}>
  40. <Button type="primary" onClick={this.showDialog}>Show Dialog</Button>
  41. <Select style={{ width: '150px' }} dataSource={['hello', 'bye']} />
  42. <RangePicker showTime/>
  43. <Calendar style={{ width: '350px', padding: '12px', border: '1px solid #C4C6CF', borderRadius: '3px' }} shape="card" />
  44. <Timeline fold={[{foldArea: [1, 2], foldShow: true}]}>
  45. <Timeline.Item title="Signed" content="Signed, sign Alibaba is a small post office, thanks to the use of STO, look forward to once again at your service" time={'2016-06-10 10:30:00'} state="process"/>
  46. <Timeline.Item title="Ship" content="Express has arrived in Hangzhou, Zhejiang Binjiang company" time={'2016-06-10 09:30:00'} />
  47. <Timeline.Item title="Ship" content="Zhejiang Hangzhou Riverside company sent a member for you to send pieces" time={'2016-06-10 09:03:00'} />
  48. <Timeline.Item title="Ship" content="Zhejiang Hangzhou Transshipment Center has been issued" time={'2016-06-10 06:10:00'} />
  49. </Timeline>
  50. <Menu className="my-menu" defaultOpenKeys="sub-menu">
  51. <Item key="1">Option 1</Item>
  52. <Item disabled key="2">Disabled option 2</Item>
  53. <Divider key="divider" />
  54. <Group label="Group">
  55. <Item key="group-1">Group option 1</Item>
  56. <Item key="group-2">Group option 2</Item>
  57. </Group>
  58. <Divider />
  59. <SubMenu key="sub-menu" label="Sub menu">
  60. <Item key="sub-1">Sub option 1</Item>
  61. <Item key="sub-2">Sub option 2</Item>
  62. <Item disabled key="sub-3">
  63. <a href="https://www.taobao.com/" target="__blank">Disabled Option Link 3</a>
  64. </Item>
  65. <Item key="sub-4">
  66. <a href="https://www.taobao.com/" target="__blank">Option Link 4</a>
  67. </Item>
  68. </SubMenu>
  69. <Item key="3" helper="CTRL+P">Option 3</Item>
  70. <Item disabled key="4">
  71. <a href="https://www.taobao.com/" target="__blank">Disabled Option Link</a>
  72. </Item>
  73. <Item key="5">
  74. <a href="https://www.taobao.com/" target="__blank">Option Link</a>
  75. </Item>
  76. </Menu>
  77. </div>
  78. </ConfigProvider>
  79. </div>
  80. );
  81. }
  82. }
  83. ReactDOM.render(<Demo />, mountNode);
  1. .my-menu {
  2. width: 200px;
  3. }
  4. .change-locale {
  5. border-bottom: 1px solid #d9d9d9;
  6. padding-bottom: 16px;
  7. }
  8. .locale-components > * {
  9. margin: 16px 0;
  10. display: block;
  11. }

ErrorBoundary 捕获错误

使用 <ErrorBoundary> 可以避免由于局部区域的错误,所引起的页面白屏。

ConfigProvider 全局配置 Next 组件 - 图6

查看源码在线预览

  1. import { ConfigProvider, Button } from '@alifd/next';
  2. const { ErrorBoundary, config } = ConfigProvider;
  3. class Demo extends React.Component {
  4. render() {
  5. if (this.props.throwError) {
  6. throw Error('There is something going wrong!');
  7. } else {
  8. return (
  9. <span>normal</span>
  10. );
  11. }
  12. }
  13. }
  14. const NewDemo = config(Demo);
  15. const fallbackUI = (props) => {
  16. const { error, errorInfo } = props;
  17. return <span style={{color: 'red'}}>{error.toString()}</span>;
  18. };
  19. class App extends React.Component {
  20. state = {
  21. throwError: false
  22. };
  23. onClick = () => {
  24. this.setState({
  25. throwError: true
  26. });
  27. };
  28. render() {
  29. return (<div>
  30. Click to throw an error <Button type="primary" onClick={this.onClick}>trigger error</Button>
  31. <br/>
  32. <br/>
  33. Default fallback UI:
  34. <hr />
  35. <ConfigProvider errorBoundary>
  36. <NewDemo throwError={this.state.throwError}/>
  37. </ConfigProvider>
  38. <br/>
  39. <br/>
  40. Customize fallback UI of configed Component(Basic Components / Biz Components):
  41. <hr />
  42. <ConfigProvider errorBoundary={{
  43. fallbackUI: props => {
  44. const { error, errorInfo } = props;
  45. return <span style={{color: 'red'}}>Error: {error.toString()}</span>;
  46. },
  47. afterCatch: () => {
  48. console.log('catching');
  49. }
  50. }}>
  51. <NewDemo throwError={this.state.throwError}/>
  52. </ConfigProvider>
  53. </div>);
  54. }
  55. }
  56. ReactDOM.render(<App />, mountNode);

相关区块

ConfigProvider 全局配置 Next 组件 - 图7

暂无相关区块