我将从代码开始。我有一个类似于这个的无状态功能组件
export const Edit Topic = (_title, _text) {
const [title, setTitle] = useState(_title)
const [text, setText] = useState(_text)
return (
<>
<InputText props={{ fieldName:"Title:", value:title, setValue:setTitle, placeHolder:"Topic Title"}}/>
<InputTextArea props={{ fieldName:"Markdown Text:", text, setText }}/>
<PreviewBox text={text}/>
</>
)
}
我有 PreviewBox
,当它打开时,页面呈现需要更长的时间,因为 text
可能很长。每次我更改 PreviewBox
中的文本时,InputTextArea
都需要重新渲染,这很好。
我遇到的问题是,当我更改 title
的值时,它也会更新 <PreviewBox/>
,这是不希望的。
如何确保 <PreviewBox/>
仅在 text
更改时更新,而在 title
更改时不更新?
我相信重新渲染正在发生的原因是因为如果我关闭 PreviewBox
,更新 title
时没有延迟,但是当 PreviewBox
可见时,更新 { {1}} 滞后。
title
由于上面还包含 import style from "../styles/CreateTopic.module.css"
import { Component } from "react"
import Markdown from "./Markdown";
export class PreviewBox extends Component {
constructor(props) {
super(props)
this.state = {
isShow: true
}
}
toggleShow = () => {
console.log("begin isShow", this.state)
this.setState(state => ({ isShow: !state.isShow}))
}
render() {
return (
<>
<div className={style.wrptoggle}>
<button className={style.btn} onClick={this.toggleShow}>Preview</button>
</div>
{this.state.isShow ?
<div className={style.wrppreviewbox}>
<div className={style.previewbox}>
<Markdown text={this.props.text}/>
</div>
</div>
: null}
</>
)
}
}
,这里是那个组件:
<Markdown/>
答案 0 :(得分:1)
我没有看到 PreviewBox
中的任何复杂性会导致任何渲染延迟,因此我可能认为它是 Markdown
组件在重新渲染时可能需要一些时间“工作”,因为您说“切换关闭 PreviewBox
,更新 title
时没有延迟。
您可以使用 memo 高阶组件来装饰 Markdown
组件并提供自定义的 areEqual
props 比较函数。
import { memo } from 'react';
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";
import ReactMarkdown from "react-markdown";
import "katex/dist/katex.min.css";
const Markdown = ({ text }) => {
return (
<div>
<ReactMarkdown
remarkPlugins={[remarkMath]}
rehypePlugins={[rehypeKatex]}
children={text}
/>
</div>
);
};
export default memo(Markdown);
<块引用>
默认情况下,它只会浅比较 props 中的复杂对象 目的。如果您想控制比较,您还可以提供 自定义比较函数作为第二个参数。
const areEqual = (prevProps, nextProps) => {
return prevProps.text === nextProps.text;
};
export default memo(Markdown, areEqual);