From 2f3a68c8c6ae1502cee6354c955ece100edbc02c Mon Sep 17 00:00:00 2001 From: Tobias Schmidt Date: Mon, 30 Apr 2018 14:20:25 +0200 Subject: [PATCH] Editable tags: Update state when props change, fixes #41 see 6775f3b0de09eea1007478e7d47372676c233769 for further details --- src/components/tagsEditable/index.js | 28 ++++++++++++---- .../tagsEditable/tests/index.test.js | 32 +++++++++++++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 src/components/tagsEditable/tests/index.test.js diff --git a/src/components/tagsEditable/index.js b/src/components/tagsEditable/index.js index 2daa73a..cf47a13 100644 --- a/src/components/tagsEditable/index.js +++ b/src/components/tagsEditable/index.js @@ -11,12 +11,8 @@ export default class TagsEditable extends Component { this.handleBlur = this.handleBlur.bind(this); this.state = { - tags: props.tags.map(tag => { - return { id: null, name: tag }; - }), - suggestions: props.suggestions.map(tag => { - return { id: null, name: tag }; - }) + tags: this.formatTags(props.tags), + suggestions: this.formatTags(props.suggestions) }; } @@ -27,6 +23,15 @@ export default class TagsEditable extends Component { suggestions: PropTypes.array }; + /** + * Format tags to match react-tags-autocomplete format + * + * @param {Array} tags flat array + * + * @return {Array.} formatted array with objects + */ + formatTags = tags => tags.map(tag => ({ id: null, name: tag })); + handleTagDelete(i) { const { state, props } = this; @@ -78,6 +83,17 @@ export default class TagsEditable extends Component { ); } + componentWillReceiveProps(nextProps) { + // copy tag props to state on update + if (nextProps.tags !== this.props.tags) { + this.setState({ tags: this.formatTags(nextProps.tags) }); + } + // copy suggestion props to state on update + if (nextProps.suggestions !== this.props.suggestions) { + this.setState({ suggestions: this.formatTags(nextProps.suggestions) }); + } + } + render(props) { // TODO nicer style classes const classNames = { diff --git a/src/components/tagsEditable/tests/index.test.js b/src/components/tagsEditable/tests/index.test.js new file mode 100644 index 0000000..c11a19b --- /dev/null +++ b/src/components/tagsEditable/tests/index.test.js @@ -0,0 +1,32 @@ +import { h } from 'preact'; +import TagsEditable from '../index.js'; +import { shallow } from 'preact-render-spy'; + +const testTags1 = ['a', 'b', 'c']; +const testTags2 = ['a', 'd', 'c', 'f']; + +const testSuggestions1 = ['suggestion', 12341, 'other suggestion']; +const testSuggestions2 = ['more ', 'more', 'test']; + +describe('Test that data is copied from props to state', () => { + const context = shallow( + + ); + test('State should match the props', () => { + expect(context.state('tags').map(tag => tag.name)).toEqual(testTags1); + }); + test('State should update when props change', () => { + context.render( + + ); + expect(context.state('tags').map(tag => tag.name)).toEqual(testTags2); + }); +});