我使用了约150个输入的表,如何避免不必要的重新渲染?
示例:
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"));
在线演示:https://codesandbox.io/s/ecstatic-curran-zngwu
我发现了如何使用useCallback,useMemo解决此问题,我尝试了很多次但都失败了,您可以指导我吗?
我尝试了下面的表格,但是没有用:https://codesandbox.io/s/wild-cherry-ue46i
答案 0 :(得分:1)
您需要为组件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"));