diff --git a/examples/simple.js b/examples/simple.js index 8aee3be..b6c1f82 100644 --- a/examples/simple.js +++ b/examples/simple.js @@ -49,11 +49,37 @@ function manualClose() { }); } +let counter = 0; +let intervalKey; +function updatableFn() { + if (counter !== 0) { + return; + } + + const key = 'updatable-notification'; + const initialProps = { + content: `Timer: ${counter}s`, + key, + duration: null, + closable: true, + onClose() { + clearInterval(intervalKey); + counter = 0; + }, + } + + notification.notice(initialProps); + intervalKey = setInterval(() => { + notification.notice({ ...initialProps, content: `Timer: ${++counter}s` }); + }, 1000); +} + ReactDOM.render(
+
, document.getElementById('__react-content')); diff --git a/src/Notice.jsx b/src/Notice.jsx index 8bf5bec..f953010 100644 --- a/src/Notice.jsx +++ b/src/Notice.jsx @@ -28,6 +28,12 @@ export default class Notice extends Component { this.clearCloseTimer(); } + componentDidUpdate(prevProps) { + if (this.props.duration !== prevProps.duration) { + this.restartCloseTimer(); + } + } + close = () => { this.clearCloseTimer(); this.props.onClose(); @@ -48,6 +54,11 @@ export default class Notice extends Component { } } + restartCloseTimer() { + this.clearCloseTimer(); + this.startCloseTimer(); + } + render() { const props = this.props; const componentClass = `${props.prefixCls}-notice`; diff --git a/src/Notification.jsx b/src/Notification.jsx index ff483e4..309d61f 100644 --- a/src/Notification.jsx +++ b/src/Notification.jsx @@ -47,11 +47,17 @@ class Notification extends Component { const key = notice.key = notice.key || getUuid(); this.setState(previousState => { const notices = previousState.notices; - if (!notices.filter(v => v.key === key).length) { - return { - notices: notices.concat(notice), - }; + const noticeIndex = notices.map(v => v.key).indexOf(notice.key); + let updatedNotices; + if (noticeIndex === -1) { + updatedNotices = notices.concat(notice); + } else { + updatedNotices = notices.concat(); + updatedNotices.splice(noticeIndex, 1, notice); } + return { + notices: updatedNotices, + }; }); } diff --git a/tests/index.js b/tests/index.js index 7d48538..1c50c64 100644 --- a/tests/index.js +++ b/tests/index.js @@ -130,6 +130,44 @@ describe('rc-notification', () => { }); }); + it('update notification by key with multi instance', (done) => { + Notification.newInstance({}, notification => { + const key = 'updatable'; + const value = 'value'; + const notUpdatableValue = 'not-updatable-value'; + notification.notice({ + content:

{notUpdatableValue}

, + duration: null, + }); + notification.notice({ + content:

{`${value}-old`}

, + key, + duration: null, + }); + notification.notice({ + content:

{value}

, + key, + duration: 0.1, + }); + + setTimeout(() => { + // Text updated successfully + expect(document.querySelectorAll('.updatable').length).to.be(1); + expect(document.querySelector('.updatable').innerText).to.be(value); + + setTimeout(() => { + // Other notices are not affected + expect(document.querySelectorAll('.not-updatable').length).to.be(1); + expect(document.querySelector('.not-updatable').innerText).to.be(notUpdatableValue); + // Duration updated successfully + expect(document.querySelectorAll('.updatable').length).to.be(0); + notification.destroy(); + done(); + }, 500); + }, 10); + }); + }); + it('freeze notification layer when mouse over', (done) => { Notification.newInstance({}, notification => { notification.notice({