简体   繁体   English

如何避免在 React 中重新渲染?

[英]How to avoid re-render in React?

I am making a simple accordion which has text editor inside it.我正在制作一个简单的手风琴,里面有文本编辑器。

If we click expand text then the text editor gets opened and if we enter some text inside the editor and click shrink, then the accordion gets closed.如果我们单击展开文本,那么文本编辑器就会打开,如果我们在编辑器中输入一些文本并单击收缩,那么手风琴就会关闭。

Again if click on the expand text of accordion where we made the changes, then the text already entered is missing inside it.同样,如果单击我们进行更改的手风琴的展开文本,则其中已输入的文本将丢失。

I can understand that this re render every time we click on the expand text.我可以理解,每次我们单击展开文本时都会重新渲染。 Also this code,还有这段代码,

<Text>  {toggleValue === index && item.content && <EditorContainer />} </Text>

check for the item clicked then it gets opened so re render happens here and hence I am losing the entered text.检查点击的项目然后它被打开,所以重新渲染发生在这里,因此我丢失了输入的文本。

Complete working example:完整的工作示例:

https://codesandbox.io/s/react-accordion-forked-dcqbo https://codesandbox.io/s/react-accordion-forked-dcqbo

Could you please kindly help me to retain the value entered inside the text editor despite of the clicks over the text Expand/Shrink?尽管点击了文本展开/收缩,您能帮我保留在文本编辑器中输入的值吗?

Put the editor's state into a persistent parent component.把编辑器的state放到一个持久化的父组件中。 Since the NormalAccordion encompasses all editors, and you want persistent state just one editor, use another component, so that the state doesn't get lost when the editor unmounts, then pass it down for the editor to use:由于NormalAccordion包含所有编辑器,并且您希望持久化 state 只是一个编辑器,请使用另一个组件,以便 state 在编辑器卸载时不会丢失,然后将其传递给编辑器使用:

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>
);

You could also put the state into the text_editor itself, and always render that container, but only conditionally render the <Editor .您还可以将 state 放入text_editor本身,并始终呈现该容器,但仅有条件地呈现<Editor

You need to save the entered text and pass it as props from the parent component to EditorContainer.您需要保存输入的文本并将其作为 props 从父组件传递给 EditorContainer。

Right now everytime you render it (eg when we click expand) It looks like you set an empty state.现在每次渲染它时(例如,当我们单击展开时)看起来您设置了一个空的 state。

Something like:就像是:

EditorContainer编辑容器

  editorState: this.props.editorState || EditorState.createEmpty()

  onEditorStateChange = (editorState) => {
    // console.log(editorState)
    this.props.setEditorState(editorState);
  };

And in Accordion :手风琴中:

{toggleValue === index && 
 item.content && 
<EditorContainer 
editorState={this.state.editorState[index]} 
setEditorState={newText => this.setState({...this.state, newText}) />}

Didn't try to execute it, but I think that's the way to achieve it.没有尝试执行它,但我认为这就是实现它的方法。 Ps: Class components are almost not used anymore. ps:Class组件几乎不用了。 Try to use function components and learn about useState hook, looks so much cleaner in my opinion尝试使用 function 组件并了解useState钩子,在我看来看起来更干净

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM