[英]Reactjs - how to use useCallback, useMemo optimizes performance
I used a table with ~ 150 inputs, how to avoid unnecessary re-render?我使用了一个大约有 150 个输入的表,如何避免不必要的重新渲染?
Example:例子:
import React, { useState, forwardRef } from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Table, Input, Form, Button } from "antd";
const initData = () => {
const data = [];
for (let i = 0; i < 300; i++) {
data.push({
key: i,
name: `King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`
});
}
return data;
};
function TableComponent({ value }, ref) {
const [data, setData] = useState(value);
const handleChange = (value, index) => {
const newData = [...data];
data[index].name = value;
setData(newData);
};
const columns = [
{
title: "Name",
dataIndex: "name",
width: 300,
render: (text, record, index) => (
<Input
value={text}
onChange={({ target: { value } }) => handleChange(value, index)}
/>
)
},
{
title: "Age",
dataIndex: "age",
width: 150
},
{
title: "Address",
dataIndex: "address"
}
];
return (
<Table ref={ref} columns={columns} dataSource={data} pagination={false} />
);
}
TableComponent = forwardRef(TableComponent);
class Demo extends React.Component {
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log("Received values of form: ", values);
}
});
};
render() {
const { getFieldDecorator } = this.props.form;
return (
<Form layout="inline" onSubmit={this.handleSubmit}>
<Form.Item>
{getFieldDecorator("table", {
initialValue: initData()
})(<TableComponent />)}
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
}
}
const WrappedDemo = Form.create({ name: "customized_form_controls" })(Demo);
ReactDOM.render(<WrappedDemo />, document.getElementById("container"));
Demo online: https://codesandbox.io/s/ecstatic-curran-zngwu在线演示: https : //codesandbox.io/s/ecstatic-curran-zngwu
I found out how to use useCallback, useMemo to solve this problem, I tried many times but failed, can you guide me?我找到了如何使用useCallback、useMemo来解决这个问题,我试了很多次都失败了,你能指导我吗?
I tried the form below, but it didn't work: https://codesandbox.io/s/wild-cherry-ue46i我尝试了下面的表格,但没有用: https : //codesandbox.io/s/wild-cherry-ue46i
You need to React.memo()
for your component and useCallback
for your state actions.您需要为您的组件使用
React.memo()
并为您的状态操作使用useCallback
。
import React, { useState, forwardRef, useCallback } from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Table, Input, Form, Button } from "antd";
const initData = () => {
const data = [];
for (let i = 0; i < 300; i++) {
data.push({
key: i,
name: `King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`
});
}
return data;
};
const CustomInput = React.memo(({ value, index, handleChange }) => (
<span>
{console.log("Rendered!")}
<Input
value={value}
index={index}
onChange={({ target: { value } }) => handleChange(value, index)}
/>
</span>
));
function TableComponent({ value = {}, onChange }, ref) {
const [data, setData] = useState(value);
const triggerChange = useCallback(
changedValue => {
if (onChange) {
setData(changedValue);
onChange(changedValue);
}
},
[onChange]
);
const handleChange = useCallback(
(value, index) => {
data[index].name = value;
triggerChange(data);
},
[triggerChange, data]
);
const columns = [
{
title: "Name",
dataIndex: "name",
width: 300,
render: (text, record, index) => (
<CustomInput value={text} index={index} handleChange={handleChange} />
)
},
{
title: "Age",
dataIndex: "age",
width: 150
},
{
title: "Address",
dataIndex: "address"
}
];
return (
<Table ref={ref} columns={columns} dataSource={data} pagination={false} />
);
}
TableComponent = forwardRef(TableComponent);
class Demo extends React.Component {
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log("Received values of form: ", values);
}
});
};
render() {
const { getFieldDecorator } = this.props.form;
return (
<Form layout="inline" onSubmit={this.handleSubmit}>
<Form.Item>
{getFieldDecorator("table", {
initialValue: initData()
})(<TableComponent />)}
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
}
}
const WrappedDemo = Form.create({ name: "customized_form_controls" })(Demo);
ReactDOM.render(<WrappedDemo />, document.getElementById("container"));
https://codesandbox.io/s/patient-sunset-8by5s https://codesandbox.io/s/patient-sunset-8by5s
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.