问题描述
我正在制作一个带有文本编辑器的简单手风琴。
如果单击扩展文本,则将打开文本编辑器;如果在编辑器中输入一些文本,然后单击收缩,则手风琴将关闭。
再次单击我们进行更改的手风琴的展开文本,则其中已经输入的文本会丢失。
我了解到,每次我们单击扩展文本时,都会重新渲染。还有这段代码,
<Text> {toggleValue === index && item.content && <EditorContainer />} </Text>
检查单击的项目,然后将其打开,以便在此处进行重新渲染,因此我丢失了输入的文本。
完整的工作示例:
尽管单击了文本“展开/收缩”,您能否请我保留在文本编辑器中输入的值?
解决方法
将编辑器的状态放入持久的父组件中。由于NormalAccordion
包含所有编辑器,并且您只希望持久状态为一个编辑器,因此请使用另一个组件,这样在卸载该编辑器时状态不会丢失,然后将其传递给编辑器使用:
const OuterEditorContainer = ({ toggleValue,setToggleValue,item,index }) => {
const [editorState,setEditorState] = useState(EditorState.createEmpty());
const toggleHandler = (index) => {
index === toggleValue ? setToggleValue(-1) : setToggleValue(index);
};
return (
<Accordion>
<Heading>
<div
style={{ padding: "10px",cursor: "pointer" }}
className="heading"
onClick={() => toggleHandler(index)}
>
{toggleValue !== index ? `Expand` : `Shrink`}
</div>
</Heading>
<Text>
{toggleValue === index && item.content && (
<EditorContainer {...{ editorState,setEditorState }} />
)}
</Text>
</Accordion>
);
};
const NormalAccordion = () => {
const [toggleValue,setToggleValue] = useState(-1);
return (
<div className="wrapper">
{accordionData.map((item,index) => (
<OuterEditorContainer
{...{ toggleValue,index }}
/>
))}
</div>
);
};
// text_editor.js
export default ({ editorState,setEditorState }) => (
<div className="editor">
<Editor
editorState={editorState}
onEditorStateChange={setEditorState}
toolbar={{
inline: { inDropdown: true },list: { inDropdown: true },textAlign: { inDropdown: true },link: { inDropdown: true },history: { inDropdown: true }
}}
/>
</div>
);
您还可以将状态放入text_editor
本身,并始终渲染该容器,但仅有条件地渲染<Editor
。
您需要保存输入的文本,并将其作为道具从父组件传递到EditorContainer。
现在,每次渲染时(例如,当我们单击“展开”时) 好像您设置了一个空状态。
类似的东西:
EditorContainer
editorState: this.props.editorState || EditorState.createEmpty()
onEditorStateChange = (editorState) => {
// console.log(editorState)
this.props.setEditorState(editorState);
};
在手风琴中:
{toggleValue === index &&
item.content &&
<EditorContainer
editorState={this.state.editorState[index]}
setEditorState={newText => this.setState({...this.state,newText}) />}
没有尝试执行它,但是我认为这是实现它的方法。 附言:类组件几乎不再使用。尝试使用功能组件并了解useState钩子,我认为它看起来更干净