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

Proper Approach to Using an Image Handler #961

Open
ryxxn opened this issue Mar 28, 2024 · 1 comment
Open

Proper Approach to Using an Image Handler #961

ryxxn opened this issue Mar 28, 2024 · 1 comment

Comments

@ryxxn
Copy link

ryxxn commented Mar 28, 2024

Problem

Using document.createElement to implement an image handler in React-Quill can lead to unexpected bugs.

A significant issue is that the upload function fails to update with dynamically changing props or states. Once created, the function does not adapt to reflect updates in the component's props or state.

Example

export default function Editor({ value, onChange, ...other }) {
  const quillRef = useRef(null);

  const imageHandler = () => {
    const input = document.createElement('input');
    input.setAttribute('type', 'file');
    input.setAttribute('accept', 'image/*');
    input.click();

    input.addEventListener('change', () => {
      const files = input.files;
      // image upload function
    });
  };

  const modules = useMemo(() => {
    return {
      toolbar: {
        container: '--',
        handlers: {
          image: imageHandler,
        },
      },
      history: {},
      clipboard: {},
      // custom
    };
  }, []);

  return (
      <ReactQuill
        ref={quillRef}
        theme="snow"
        modules={modules}
        formats={formats}
        value={value}
        onChange={onChange}
        placeholder="input text..."
        {...other}
      />
  );
}

Solution

To address these issues, it's recommended to use React's useRef to reference the file input tag. This approach allows for managing DOM elements within React, thereby preventing synchronization issues between React's virtual DOM and the actual DOM. Here's a simplified example of how this can be implemented.

export default function Editor({ value, onChange, ...other }) {
  const inputRef = useRef(null);

  const quillRef = useRef(null);

  const onChangeImage = () => {
    const files = inputRef.current.files;
    // Image upload function
  };

  const modules = useMemo(() => {
    return {
      toolbar: {
        container: '--',
        handlers: {
          image: () => inputRef.current.click(),
        },
      },
      history: {},
      clipboard: {},
      // Custom modules
    };
  }, []);

  return (
    <div>
      <input
        ref={inputRef}
        className="hide" // hide
        type="file"
        onChange={onChangeImage}
      />
      <ReactQuill
        ref={quillRef}
        theme="snow"
        modules={modules}
        formats={formats}
        value={value}
        onChange={onChange}
        placeholder="input text..."
        {...other}
      />
    </div>
  );
}
@alilland
Copy link

any advice on hooking into the editor in order to react to the image in the editor pallet?

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

No branches or pull requests

2 participants