Рендеринг нескольких полей ввода, вызывающий отставание после 200 элементов - PullRequest
1 голос
/ 07 апреля 2020

У меня есть проект, где я могу иметь n-номер поля ввода. После того, как я добавляю 200 предметов, после этого начинается отставание. Демонстрация: https://testcreate.vivekneel.now.sh/create (Для проверки: сфокусировать последний вход и попытаться нажать кнопку ввода, чтобы создать новый вход)

Исходный код. : https://github.com/VivekNeel/Create-Test

Это мой основной контейнер:

import React, { useState } from "react";

import CreateTerms from "./CreateTerms";
import { initTerms, contructTermObject } from "./utils";
import { Container } from "@material-ui/core/";

const CreateStudySetContainer = () => {
  const [terms, setTerms] = useState(initTerms);

  const [inputIdToFocus, setInputIdToFocus] = useState(null);

  const handleCreateTerm = () => {
    const newTerm = contructTermObject(terms.length + 1, 2);
    const newTerms = [...terms, newTerm];
    setInputIdToFocus(terms.length + 1);
    setTerms(newTerms);
  };
  console.log("....rendering");
  return (
    <Container maxWidth={"md"}>
      <CreateTerms
        terms={terms}
        inputIdToFocus={inputIdToFocus}
        createTerm={handleCreateTerm}
      />
      ;
    </Container>
  );
};

export default CreateStudySetContainer;

Это код CreateTerms:

import React from "react";
import CreateFacts from "./CreateFacts";

import { withStyles, Card } from "@material-ui/core/";
import ContentItemRow from "./ContentItemRow";
const styles = () => ({
  card: {
    marginBottom: 16,
  },
});
const CreateTerms = (props) => {
  const { terms, classes, createTerm, inputIdToFocus } = props;
  return (
    <div className={classes.container}>
      {terms.map(({ node: { term } }, index) => {
        return (
          <Card key={term.id} className={classes.card}>
            <p>{index}</p>
            <ContentItemRow
              autoFocus={term.id === inputIdToFocus}
              createTerm={createTerm}
              term={term}
            />
            ;
          </Card>
        );
      })}
    </div>
  );
};

export default withStyles(styles)(CreateTerms);

Это ContentItemRow:

import React from "react";
import CreateFacts from "./CreateFacts";

import { withStyles } from "@material-ui/core/";
import ContentEditor from "./ContentEditor";
const styles = {
  container: {
    display: "flex",
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "flex-start",
  },
  term: {
    marginRight: 16,
    flex: 1,
  },
  facts: {
    flex: 1,
  },
};

const ContentItemRow = (props) => {
  const { term, classes, createTerm, autoFocus } = props;
  return (
    <div className={classes.container}>
      <div className={classes.term}>
        <ContentEditor
          autoFocus={autoFocus}
          createTerm={createTerm}
          placeholder={"New term"}
        />
      </div>
      <div className={classes.facts}>
        {term.facts.map(({ fact }) => {
          return (
            <ContentEditor
              key={fact.id}
              createTerm={createTerm}
              placeholder={"New fact"}
            />
          );
        })}
      </div>
    </div>
  );
};

export default withStyles(styles)(ContentItemRow);

Это ContentEditor:

import React from "react";

import { TextField } from "@material-ui/core/";

const ContentEditor = (props) => {
  const { placeholder, createTerm, autoFocus } = props;

  const handleOnKeyDown = (event) => {
    const { keyCode } = event;
    if (keyCode === 13) {
      createTerm();
    }
  };
  return (
    <TextField
      onKeyDown={handleOnKeyDown}
      fullWidth
      autoFocus={autoFocus}
      placeholder={placeholder}
    />
  );
};

export default ContentEditor;

При отладке я заметил, что dom обновляет только последний добавленный div. Я не знаю, откуда идет отставание.

1 Ответ

1 голос
/ 07 апреля 2020

Не уверен, что это будет работать, но вы можете попробовать следующее:

const ContentItemRow = React.memo(function ContentItemRow (props) => {

И чтобы предотвратить повторное создание обработчика создания термина:

const handleCreateTerm = useCallback(() => {
  setTerms((terms) => {
    const newTerm = contructTermObject(
      terms.length + 1,
      2
    );
    const newTerms = [...terms, newTerm];
    setInputIdToFocus(terms.length + 1);
    return newTerms;
  });
}, []);
...