如何避免在 React 中重新渲染?
How to avoid re-render in React?
我正在制作一个简单的手风琴,里面有文本编辑器。
如果我们点击展开文本,那么文本编辑器就会打开,如果我们在编辑器中输入一些文本,然后点击收缩,那么手风琴就会关闭。
同样,如果单击我们进行更改的手风琴的展开文本,则已经输入的文本在其中丢失。
我可以理解每次点击展开文本时都会重新渲染。还有这段代码,
<Text> {toggleValue === index && item.content && <EditorContainer />} </Text>
检查点击的项目然后它被打开,所以重新渲染发生在这里,因此我丢失了输入的文本。
完整的工作示例:
尽管点击了文本,您能否帮我保留在文本编辑器中输入的值 Expand/Shrink?
将编辑器的状态放入持久化父组件中。由于 NormalAccordion
包含所有编辑器,并且您只需要 one 编辑器保持状态,请使用另一个组件,以便在卸载编辑器时状态不会丢失,然后通过下来供编辑使用:
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, setToggleValue, item, 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
.
您需要保存输入的文本并将其作为 props 从父组件传递给 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}) />}
没有尝试执行它,但我认为这是实现它的方式。
Ps: Class 组件几乎不用了。尝试使用函数组件并了解 useState hook,在我看来看起来更干净
我正在制作一个简单的手风琴,里面有文本编辑器。
如果我们点击展开文本,那么文本编辑器就会打开,如果我们在编辑器中输入一些文本,然后点击收缩,那么手风琴就会关闭。
同样,如果单击我们进行更改的手风琴的展开文本,则已经输入的文本在其中丢失。
我可以理解每次点击展开文本时都会重新渲染。还有这段代码,
<Text> {toggleValue === index && item.content && <EditorContainer />} </Text>
检查点击的项目然后它被打开,所以重新渲染发生在这里,因此我丢失了输入的文本。
完整的工作示例:
尽管点击了文本,您能否帮我保留在文本编辑器中输入的值 Expand/Shrink?
将编辑器的状态放入持久化父组件中。由于 NormalAccordion
包含所有编辑器,并且您只需要 one 编辑器保持状态,请使用另一个组件,以便在卸载编辑器时状态不会丢失,然后通过下来供编辑使用:
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, setToggleValue, item, 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
.
您需要保存输入的文本并将其作为 props 从父组件传递给 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}) />}
没有尝试执行它,但我认为这是实现它的方式。 Ps: Class 组件几乎不用了。尝试使用函数组件并了解 useState hook,在我看来看起来更干净