简体   繁体   English

Reactjs——如何使用useCallback、useMemo优化性能

[英]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.

相关问题 何时使用 useMemo 和 useCallback 进行性能优化? - When to use useMemo and useCallback for performance optimization? 这是对 useCallback 和 useMemo 的错误使用吗? - Is this incorrect use of useCallback and useMemo? 何时使用 useCallback、useMemo 和 useEffect? - When to use useCallback, useMemo and useEffect? 为什么在这里使用 useMemo 而不是 useCallback? - Why use useMemo and not useCallback here? 当依赖项是 object 时,如何使用 useCallback、useMemo 和 React.memo? - How to use useCallback, useMemo and React.memo when dependency is an object? useCallback 与 useMemo 以及何时使用它们 - useCallback vs. useMemo and when to use them 如何在按钮单击时触发 useCallback、useMemo 或 useEffect? - How to trigger useCallback, useMemo or useEffect on button click? React - 如何用 useMemo 替换 useCallback 钩子? - React - how to replace useCallback hook with useMemo? 我的 useMemo useCallback 不会减少渲染次数。 使用 useMemo 和 useCallback 的正确方法是什么? - My useMemo useCallback does not reduce the number of render. What is the correct way to use useMemo and useCallback? 优化 React 性能:使用带有 useMemo 或 useCallback 的 Axios GET 请求记忆功能? - Optimizing React Performance: Memoize function with Axios GET Request with useMemo or useCallback?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM