React useEffect 等价于类组件

Jas*_*son 8 reactjs react-hooks

我有一个 React 功能组件,它执行以下操作:

  • 发送 POST 以从我的 API 加载原始数据
  • (除其他外)将映射数据发送到自定义表组件
  • 允许用户使用不同的过滤器重新发送 POST
import React, { useEffect, useState } from "react";
import axios from "axios";
import mytable from "./mytable";

const baseRawData = [
  { name: "name", value: "John Doe" },
  { name: "sex", value: "M" }
];

export default function FuncComp() {
  let [rawData, setRawData] = useState(baseRawData);
  let [mappedData, setMappedData] = useState([]);
  let [apiFilter, setApiFilter] = useState("all");

  useEffect(() => {
    setMappedData(
      rawData.map(e => ({
        ...e
        // Some logic
      }))
    );
  }, [rawData]);

  useEffect(() => {
    axios.post(`/my/api/${filter}`).then(({ data }) => {
      setRawData(data);
    });
  }, [apiFilter]);

  return (
    <div>
      <h1>The filter is '{apiFilter}'</h1>
      <mytable data={mappedData} />
      <input
        value={apiFilter}
        onBlur={e => setApiFilter(e.target.value)}
        type="text"
      />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

在类组件中,如何实现与useEffect相同的逻辑,以在每次用户更改过滤器并收到新的原始数据时映射新接收的原始数据?

小智 2

在将其转换回类组件之前,我会像这样简化功能组件

import React, { useEffect, useState } from "react";
import axios from "axios";
import mytable from "./mytable";

const baseRawData = [
  { name: "name", value: "John Doe" },
  { name: "sex", value: "M" }
];

const mapData = rawData => rawData.map(e => ({
  ...e
  // Some logic
}));

export default function FuncComp() {
  let [mappedData, setMappedData] = useState(mapData(baseRawData));
  let [apiFilter, setApiFilter] = useState("all");

  useEffect(() => {
    axios.post(`/my/api/${apiFilter}`).then(({ data }) => {
      setMappedData(mapData(data));
    });
  }, [apiFilter]);

  return (
    <div>
      <h1>The filter is '{apiFilter}'</h1>
      <mytable data={mappedData} />
      <input
        value={apiFilter}
        onBlur={e => setApiFilter(e.target.value)}
        type="text"
      />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

然后您可以将 useState 转换为简单的状态变量。我没有运行代码,但它应该是这样的。

import React from "react";
import axios from "axios";
import mytable from "./mytable";

const baseRawData = [
  { name: "name", value: "John Doe" },
  { name: "sex", value: "M" }
];

const mapData = rawData => rawData.map(e => ({
  ...e
  // Some logic
}));

class component extends React.Component {
  constructor() {
    this.state = {
      mappedData: mapData(baseRawData),
      apiFilter: 'all'
    }
  }

  filterChanged(newApiFilter) {
    this.setState({apiFilter: newApiFilter});
    axios.post(`/my/api/${newApiFilter}`).then(({ data }) => {
      this.setState({
        mappedData: mapData(data)
      })
    });
  }

  render () {
    const {apiFilter, mappedData} = this.state;
    return (
      <div>
        <h1>The filter is '{apiFilter}'</h1>
        <mytable data={mappedData} />
        <input
          value={apiFilter}
          onBlur={e => this.filterChanged(e.target.value)}
          type="text"
        />
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然简化是一个好主意,但这设法回避了实际提出的问题——当依赖状态发生变化时,如何使用等效的“useEffect”?这基本上是说“不要尝试”,这在很多情况下可能不可行。 (23认同)