Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RichTextInput inside ArrayInput deletion issue #3220

Closed
cherniavskii opened this issue May 14, 2019 · 5 comments
Closed

RichTextInput inside ArrayInput deletion issue #3220

cherniavskii opened this issue May 14, 2019 · 5 comments
Labels

Comments

@cherniavskii
Copy link
Contributor

cherniavskii commented May 14, 2019

When using RichTextInput inside ArrayInput, deletion of single element doesn't work as expected.

What you were expecting:

Clicking Remove button removes element from array

What happened instead:

Clicking Remove button removes element from array and adds new empty item instead

Steps to reproduce:

Minimal example: https://codesandbox.io/s/zr7r9pn52p

  1. Open post edit view.
  2. Click Remove button on the last backlink item

Related code:

<ArrayInput source="backlinks">
  <SimpleFormIterator>
    <RichTextInput source="url" />
  </SimpleFormIterator>
</ArrayInput>

Other information:

mpjnt-ucdx1

Environment

  • React-admin version: 2.9.0
  • Last version that did not exhibit the issue (if applicable):
  • React version:
  • Browser:
  • Stack trace (in case of a JS error):
@cherniavskii
Copy link
Contributor Author

cherniavskii commented May 14, 2019

So, what's going on:

First of all, text-change event handler never gets removed, since it's reference is never stored:

this.quill.on('text-change', debounce(this.onTextChange, 500));

Second of all, after removing redux-form field, RichTextInput gets updated with empty string value.
This invokes componentDidUpdate, then this.quill.setContents:

componentDidUpdate(prevProps) {
if (prevProps.input.value !== this.props.input.value) {
const selection = this.quill.getSelection();
this.quill.setContents(
this.quill.clipboard.convert(this.props.input.value)

After that, onTextChange is invoked, and finally this.props.input.onChange, which writes empty string as last array field in redux-form:

onTextChange = () => {
const value =
this.editor.innerHTML == '<p><br></p>' ? '' : this.editor.innerHTML;
this.lastValueChange = value;
this.props.input.onChange(value);

Then new array item appears with empty RichTextInput.

Proposed solution

#3221 fixes wrong debouncing handling.
But doesn't solve problem completely, because of TransitionGroup in SimpleFormIterator.
It has timeout set to 500ms (same as RichTextInput debounce timeout), so RichTextInput unmounts after debounced callback is fired.

Setting timeout to 450ms in SimpleFormIterator resolves the issue completely.

My suggestion is first add timeout prop to SimpleFormIterator. Having timeout configurable, it'll be possible to demonstrate, that changing it's value may solve the problem.

That being said, #3221 is crucial for fixing this issue.

@Kmaschta Kmaschta added the bug label May 14, 2019
@Kmaschta
Copy link
Contributor

I fixed the import error in your codesandbox : https://codesandbox.io/s/rlmq71qyj4

@cherniavskii
Copy link
Contributor Author

@Kmaschta thanks!

@cherniavskii
Copy link
Contributor Author

Workaround in user land if #3223 and #3226 got merged:

<ArrayInput source="backlinks">
-  <SimpleFormIterator>
+  <SimpleFormIterator TransitionProps={{ timeout: 400 }}>
    <RichTextInput source="url" />
  </SimpleFormIterator>
</ArrayInput>

@fzaninotto
Copy link
Member

Cannot reproduce anymore on master (v3.16), it was probably solved by a previous PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants