@contentful/field-editor-rich-text re-rendering problem
See original GitHub issueHi all, I am using @contentful/field-editor-rich-text in a contentful app, version 2.1.0 and I have some problems with rerendering. Basically I am rendering a set of tabs and each tab has an instance of @contentful/field-editor-rich-text:
<ConnectedRichTextEditor
sdk={sdk}
value={accordion.content}
onChange={(e: any) =>
setGlobalData((prevState) => {
const newState = [...prevState];
newState[idx].content = e;
return newState;
})}
minHeight={"300px"}
/>
When the component first renders it works great, but as soon as I change tab, the editor disappears and never reappears even when I return to the original tab. When the page is reloaded the editor reappears, only to disappear again as soon as a new tab is selected. I also tried to render all the editors together without tabs: what happens is that all the editors have the content of the last rendered editor, which is not ideal.
Here is the full Field component
const Field = () => {
const sdk = useSDK<FieldExtensionSDK>();
const [globalData, setGlobalData] = useState<AccordionData[]>(
sdk.field.getValue() || [{ title: "", content: emptyRTF }]
);
const [currentTab, setCurrentTab] = useState("accordion-0");
useEffect(() => {
sdk.window.startAutoResizer();
});
useEffect(() => {
if (globalData && sdk.field.getValue() !== globalData) {
sdk.field.setValue(globalData).then();
}
}, [globalData, sdk.field]);
return (
<>
<Note style={{ marginTop: "10px", marginBottom: "20px" }}>
You can create more than one accordion in this component. Use "Add
Accordion" to create one. If you want to delete a particular accordion
you can use the "Delete Accordion" button of the relative Accordion.
</Note>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<Button
style={{ marginBottom: "20px" }}
variant="primary"
onClick={() => {
setGlobalData((prevState) => [
...prevState,
{ title: "", content: emptyRTF },
]);
const currentIdx = parseInt(currentTab.split("-")[1]);
setCurrentTab(`accordion-${currentIdx + 1}`);
}}
>
Add Accordion
</Button>
</div>
<Tabs currentTab={currentTab} onTabChange={setCurrentTab}>
<Tabs.List>
{globalData.map((accordion, idx) => {
return (
<Tabs.Tab panelId={`accordion-${idx}`} key={`accordion-${idx}`}>
A. # {idx + 1}
</Tabs.Tab>
);
})}
</Tabs.List>
{globalData.map((accordion, idx) => {
return (
<Tabs.Panel id={`accordion-${idx}`} key={`accordion-${idx}`}>
<h2 style={{ marginTop: "20px", marginBottom: "10px" }}>Title</h2>
<TextInput
value={accordion.title}
onChange={(e: any) =>
setGlobalData((prevState) => {
const newState = [...prevState];
newState[idx].title = e.target.value;
return newState;
})
}
title={"Header"}
placeholder={"Header"}
/>
<h2 style={{ marginTop: "30px", marginBottom: "10px" }}>
Content
</h2>
<ConnectedRichTextEditor
// @ts-ignore
sdk={sdk}
value={accordion.content}
onChange={(e: any) =>
setGlobalData((prevState) => {
const newState = [...prevState];
newState[idx].content = e;
return newState;
})
}
minHeight={"300px"}
/>
<div
style={{
display: "flex",
justifyContent: "end",
alignItems: "center",
}}
>
<Button
style={{ marginTop: "20px" }}
variant="negative"
onClick={() => {
setGlobalData((prevState) => {
const newData = [...prevState];
newData.splice(idx, 1);
return newData;
});
const currentIdx = parseInt(currentTab.split("-")[1]);
setCurrentTab(
`accordion-${currentIdx >= 1 ? currentIdx - 1 : 0}`
);
}}
>
Delete Accordion
</Button>
</div>
</Tabs.Panel>
);
})}
</Tabs>
</>
);
};
Is there something I’m doing wrong when rendering the editors? Or is this a bug of the editor? Version 1 did not have this problem using the same code structure, but it did have problems selecting the text and changing it.
Issue Analytics
- State:
- Created a year ago
- Reactions:2
- Comments:6 (1 by maintainers)
Top GitHub Comments
Hi, I encountered the same issue with basically the same use case. After some debugging I tracked down the issue to the ids of the respective
ConnectedRichTextEditor
s. Internally they are passed to thePlate
component, which requires the ids to be unique. I was able to fix the issue by passing a unique id to our customConnectedRichTextEditor
implementation which replaces the internal id calculation.Unfortunately there doesn’t seem to be a fix available without rewriting the internal rich text editor logic.
Thank you so much @niclaszllaudi for pinpointing the issue in the codebase. I have used
patch-package
to make it work. This however is NOT a solution to the issue and if the devs want us to make a PR I would happily do it. For now my project is not blocked though, which is great.