我有一个项目,可以有n个输入字段。当我添加200个项目后,它开始滞后。演示:https://testcreate.vivekneel.now.sh/create(要测试:聚焦最后一个输入,并尝试按enter按钮创建新输入(
源代码: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。我不知道滞后是从哪里来的。
不确定这是否有效,但您可以尝试以下操作:
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;
});
}, []);