React infinite loop caused by onChange on Inputfield / React Quill - reactjs

im new to react and just have to update a value in onChange to filter some tags. But When I do that, it causes an infinite loop. How can I prevent that?
const Editor = ({ onChange, name, value }) => {
const modules = {
toolbar: [
[{ 'header': '1'}, {'header': '2'}, { 'font': [] }],
[{size: []}],
['bold', 'italic', 'underline','strike', 'blockquote'],
[{'list': 'ordered'}, {'list': 'bullet'}, {'indent': '-1'}, {'indent': '+1'}],
['link'],
['clean']
],
clipboard: {
matchVisual: false
}
}
return (
<ReactQuill
theme="snow"
value={value}
modules={modules}
onChange={(content, event, editor) => {
const cleanedContent = content?.replace(/<p><br><\/p>/g, '<br>');
console.log('test');
onChange({ target: { name, value: cleanedContent } });
}}/>
);
};
export default Editor;

Related

how can i set default text alignment in react-quill to right?

I want the default text-align to be right in react quill, i couldn't find a way to do that.
Here is my text editor:
import dynamic from 'next/dynamic'
import { ReactQuillProps } from 'react-quill'
import 'react-quill/dist/quill.snow.css'
const ReactQuill = dynamic(import('react-quill'), { ssr: false })
const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{ header: 1 }, { header: 2 }],
[{ list: 'ordered' }, { list: 'bullet' }],
[{ direction: 'rtl' }],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }],
[{ align: [] }],
['link', 'image', 'video'],
['clean'],
]
export default function BasicTextEditor({
value,
onChange,
placeholder,
}: {
placeholder: string
value: string
onChange: () => void
}) {
const quillProps: ReactQuillProps = {
modules: {
toolbar: toolbarOptions,
},
}
return (
<ReactQuill
className="whitespace-pre-line"
{...quillProps}
placeholder={placeholder}
theme="snow"
value={value}
onChange={onChange}
formats={[{}]}
/>
)
}
As you can see there is an option called {align: []}, i want by default my text be
Right now for me to change the alignment of the text i have to add a class manly to each element in the text but i want a better way to achieve it.

React Quill Default Value will not display with API call

I am using react quill to set an editor. I want to prepopulate the editor with data from my API, However when I use the defaultValue it does not render. I can console.log the data from the API no problem. Here is the code.....
const GET_ISP_ENTRY = gql`
query IspListEntry($ispListEntryId: ID!) {
ispListEntry(id: $ispListEntryId) {
_id
displayName
contactFirstName
contactLastName
contactTitle
lastUpdated
onlineService
onlineAttn
address
city
state
zipCode
country
phoneNumber
extension
mobileNumber
faxNumber
email
website
referTo
notes
previous
}
}
`;
const UPDATE_ISP_ENTRY = gql`
mutation UpdateISPEntry($ispListEntryUpdateId: ID!, $input: UpdateISPEntry) {
ispListEntryUpdate(id: $ispListEntryUpdateId, input: $input) {
displayName
}
}
`;
const UpdateISPEntry = () => {
const [formValues, setFormValues] = useState();
const [urlId, setUrlId] = useState('');
const [notesFromAPI, setNotesFromAPI] = useState();
const [previousState, setPreviousState] = useState();
const [getIsp, { data, loading, error }] = useLazyQuery(GET_ISP_ENTRY, {
variables: {
ispListEntryId: urlId
},
onCompleted: () => {
setNotesFromAPI(data && data.ispListEntry.notes);
},
onError: () => {
toast.error(error);
}
});
console.log(loading ? 'Loading...' : notesFromAPI);
const [
submitValues,
{ data: successful, loading: successLoading, error: loadingError }
] = useMutation(UPDATE_ISP_ENTRY, {
onError: () => {
toast.error(`There was an error ${loadingError}`);
}
});
const params = useLocation();
const path = params.pathname;
const pathSplit = path.split('/')[2];
const [notesState, setNotesState] = useState();
useEffect(() => {
getIsp();
setFormValues(data && data.ispListEntry);
setUrlId(pathSplit);
}, [data, getIsp, pathSplit, formValues]);
const handleSubmit = () => {};
return (
<Fragment>
<div className='container p-4 parent-container'>
<ISPFormHeader />
<ISPFormHeaderPagename children='Update ISP Entry' />
<ISPForm
initialValues={data && data.ispListEntry}
enableReinitialize={true}
onSubmit={handleSubmit}
/>
<div className='editor-fields'>
<EditorComponent
defaultValue={notesFromAPI}
state={notesState}
onChange={setNotesState}
/>
</div>
<div className='editor-fields'>
<EditorComponent
placeholder='Enter Previous Notes Here'
state={previousState}
onChange={setPreviousState}
/>
</div>
</div>
</Fragment>
);
};
export default UpdateISPEntry;
and the Editor Component...
import React from 'react';
import ReactQuill from 'react-quill';
const modules = {
toolbar: [
[{ font: [] }],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
['bold', 'italic', 'underline', 'strike'],
[{ color: [] }, { background: [] }],
[{ script: 'sub' }, { script: 'super' }],
['blockquote', 'code-block'],
[{ list: 'ordered' }, { list: 'bullet' }],
[{ indent: '-1' }, { indent: '+1' }, { align: [] }],
['link', 'image', 'video'],
['clean']
]
};
const EditorComponent = ({ placeholder, state, onChange, defaultValue }) => {
return (
<ReactQuill
defaultValue={defaultValue}
modules={modules}
theme='snow'
placeholder={placeholder}
state={state}
onChange={onChange}
/>
);
};
export default EditorComponent;

React quill in nextjs and typescript custom image handler issue?

I am try to use react-quill in my typescript nextjs project. Here I am finding typing and ref issue that I can't solve. Please help me.
Here is code example-
import React, { useState, useRef } from 'react';
import dynamic from 'next/dynamic';
import { Container } from "#mui/material";
const ReactQuill = dynamic(import('react-quill'), {
ssr: false,
loading: () => <p>Loading ...</p>,
})
import 'react-quill/dist/quill.snow.css';
const Editor = () => {
const [value, setValue] = useState('');
const quillRef = useRef<any>();
const imageHandler = async () => {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.click();
input.onchange = async () => {
var file: any = input && input.files ? input.files[0] : null;
var formData = new FormData();
formData.append("file", file);
let quillObj = quillRef.current.getEditor();
};
}
const modules = {
toolbar: {
container: [
[{ font: [] }, { 'size': [] }, { 'header': [1, 2, 3, 4, 5, 6] }],
['bold', 'italic', 'underline', 'strike'],
[{ 'color': [] }, { 'background': [] }],
[{ 'script': 'sub' }, { 'script': 'super' }],
[{ 'header': 1 }, { 'header': 2 }, 'blockquote', 'code-block'],
[
{ list: 'ordered' },
{ list: 'bullet' },
{ indent: '-1' },
{ indent: '+1' },
],
[{ 'direction': 'rtl' }, { 'align': [] }],
['link', 'image', 'clean'],
],
'handlers': {
image: imageHandler
}
}
}
return (
<Container maxWidth="xxxl" disableGutters>
<ReactQuill
ref={quillRef} // Here I am finding an issue.
value={value}
modules={modules}
onChange={setValue}
placeholder="Start typing!"
/>
</Container>
);
};
export default Editor;
Here is CodeSandBox-
https://codesandbox.io/s/still-hill-xkb1pj
Can any one give me a proper typescript solutions.

Some features of react-quill don't work in production

I have a Next app and Text Editor using react-quill. In localhost everything works well, but when I got my project in vercel some features of react-quill don't work, like fontSize, color of font, align and so on.
`
import { Box } from '#chakra-ui/react';
import dynamic from 'next/dynamic';
import 'react-quill/dist/quill.snow.css';
const QuillNoSSRWrapper = dynamic(import('react-quill'), {
ssr: false,
loading: () => <p>Loading ...</p>,
});
const modules = {
toolbar: [
[{ header: '1' }, { header: '2' }, 'code-block'],
[{ size: [] }],
[{ script: 'super' }, { script: 'sub' }],
[{ color: [] }, { background: [] }],
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[
'direction',
{ align: [] },
{ list: 'ordered' },
{ list: 'bullet' },
{ indent: '-1' },
{ indent: '+1' },
],
['link', 'image', 'video'],
['clean'],
],
};
const formats = [
'header',
'font',
'size',
'bold',
'italic',
'underline',
'strike',
'blockquote',
'list',
'bullet',
'indent',
'link',
'image',
'video',
'code-block',
'align',
'direction',
'color',
'background',
'script',
'super',
'sub',
];
const TextEditor = ({ setContentValue, value }: any) => {
return (
<QuillNoSSRWrapper
bounds={'.app'}
modules={modules}
formats={formats}
onChange={setContentValue}
placeholder="Write your post here. You can edit your text by tools above"
value={value}
theme="snow"
/>
);
};
export default TextEditor;
`
Here my code of TextEditor
Do you have any ideas about this?
I tried to use Text Editor react-quill that works well in development, but it doesn't work in vercel
Check if your next.config.ts has swcMinify: true. Removing this in my project helped.
More info here: ReactJs quill editor add color to text not working for deployed app

React Quill custom image handler not working

Can someone help me to find out what is the issue in the code. I have created a custom image upload option but for some reason the variable "quillReact" is coming null when quillImageCallback function is invoked. I am using react-hooks. The image is uploaded properly when using API and proper response is also returned from the backend.
let quillReact: ReactQuill | null = null;
const updateIssueInfo = (value: string, delta: any, source: any, editor: any) => {
setIssueManagementInEdit({
...issueManagementInEdit,
description: value
});
};
const quillImageCallback = () => {
console.log(issueManagement);
const input = document.createElement("input");
input.setAttribute("type","file");
input.setAttribute("accept", "image/*");
input.click();
input.onchange = async () => {
const file: File | null = input.files ? input.files[0] : null;
if(file){
uploadImage(file).then(async (fileName: any) => {
const newFileName:string = await fileName.text();
console.log(quillReact);
let quill: any | null = quillReact?.getEditor();
console.log(quill);
const range : any | null = quill?.getSelection(true);
quill?.insertEmbed(range.index, 'image', `http://localhost:8080/uploads/${newFileName}`);
});
}
}
};
const module = React.useMemo(() => { return {
toolbar: {
container: [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean', 'image'] // remove formatting button
],
handlers: {
image: quillImageCallback
}
},
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
}
}},[]);
<ReactQuill
value={issueManagementInEdit.description ? issueManagementInEdit.description : ""}
onChange={updateIssueInfo}
modules={module}
ref={(el: ReactQuill) => {
quillReact = el;
} }
style={{height: "250px"}}
id="description"
key="description"
/>
Thank You.
I suggest you try useRef:
const quillRef = React.useRef(null);
<ReactQuill ... ref={quillRef} />
And then access the editor in your callback:
const quill = quillRef.current.getEditor();

Resources