在类组件中反应等效的useEffect

时间:2020-03-01 11:12:04

标签: 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>
  );
}

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

2 个答案:

答案 0 :(得分: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>
  );
}

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

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>
    );
  }
}

答案 1 :(得分:0)

此解决方案基于以下假设;

  1. 您具有要在组件首次呈现时呈现的baseData。
  2. 一旦安装了组件,您就从api请求新数据。
  3. 如果过滤器为空,则在没有过滤器的情况下发出请求。
  4. 设置了过滤器值后,您将再次请求过滤器。

代码

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

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

export default class ClassComp extends Component{
  state = {
    rawData: baseRawData,
    mappedData: [],
    apiFilter: ""
  }

  componentDidMount() {
    axios.post(`/my/api`)
    .then(({ data }) => {
      this.setState({ mappedData : data });
    });
  }

  filterPost = (e) => {
    this.setState({ apiFilter: e.target.value},() => {
      axios.post(`/my/api/${this.state.apiFilter}`)
        .then(({ data }) => {
          this.setState({ mappedData : data });
        });
    });
  }

  render() {
    const {apiFilter, mappedData, baseRawData } = this.state;

  return (
    <div>
      <h1>The filter is '{apiFilter}'</h1>
      <mytable data={ mappedData ? mappedData : baseRawData } />
      <input
        value={apiFilter}
        onBlur={e => this.filterPost(e.target.value)}
        type="text"
      />
    </div>
  );
 }
}