首页 > 解决方案 > 上下文提供程序中的 componentDidMount() 状态更改未触发子组件的重新渲染

问题描述

这是我的代码。一直试图让它工作4天。从函数组件到类组件,再到介于两者之间的所有东西,我都尝试过。不知所措。我无法在构造函数中正确设置状态,因为它是异步的,但是在放入 componentDidMount() 时它不会重新渲染

编辑:是的,我知道有些代码是多余的。我对其进行了更改以隔离错误并删除了 addParams() 逻辑以及其他一些东西。

    import React, { Component } from "react";
import axios from "axios";
export const ListContext = React.createContext();

class ListContextProvider extends Component {
  constructor() {
    super();
    this.state = { cards: {}, params: {} };
  }

  addParams(parameters) {
    return parameters;
  }

  getCards() {
    let parameters = this.addParams({ last_name__icontains: "smith" });
    console.log(parameters);
    axios({
      method: "get",
      url: "http://127.0.0.1:8000/charges/cardsapi/",
      params: parameters,
    }).then((response) => {
      let cards = Object.values(response.data.results);
      let cardsState = Object.assign({}, cards);
      this.setState({ cards: cardsState });
      console.log(this);
      console.log(this.state);
    });
  }

  componentDidMount() {
    console.log("mounted");
    this.getCards();
  }

  render() {
    return (
      <ListContext.Provider value={this.state}>
        {this.props.children}
      </ListContext.Provider>
    );
  }
}

export { ListContextProvider };

然后是消费者:

export default function DataTable(context) {
  let cards = context;

  const rows = [];
  const headerCells = [];
  if (cards.length > 1) {
    for (let field in cards[0]) {
      headerCells.push(<TableCell key={field}>{field}</TableCell>);
    }

    for (let row of cards) {
      const cells = [];
      for (const [key, value] of Object.entries(row)) {
        cells.push(<TableCell key={key}>{value}</TableCell>);
      }
      rows.push(<TableRow key={cells[0].props.children}>{cells}</TableRow>);
    }

    return (
      <Table>
        <TableHead>
          <TableRow key={"header"}>{headerCells}</TableRow>
        </TableHead>
        <TableBody>{rows}</TableBody>
      </Table>
    );
  } else {
    return (
      <Table>
        <tbody>
          <tr>
            <td>Empty</td>
          </tr>
        </tbody>
      </Table>
    );
  }
}

标签: javascriptreactjsreact-hooksreact-componentreact-context

解决方案


这有效:

import React, { Component } from "react";
import axios from "axios";

let ListContext = React.createContext();


class ListContextProvider extends Component {
  constructor() {
    super();
    this.state = { cards: [], params: {} };
  }

  addParams(parameters) {
    this.setState({ params: parameters });
  }

  getCards() {
    let parameters = this.state.params;
    console.log(parameters);
    axios({
      method: "get",
      url: "http://127.0.0.1:8000/charges/cardsapi/",
      params: parameters,
    }).then((response) => {
      let cardsState = Object.values(response.data.results);
      this.setState({ cards: cardsState });
    });
  }

  async componentDidMount() {
    await this.addParams({ last_name__icontains: "shaer" });
    console.log("mounted");
    this.getCards();
  }

  render() {
    return (
      <ListContext.Provider value={this.state}>
        {this.props.children}
      </ListContext.Provider>
    );
  }
}

export { ListContextProvider, ListContext };

推荐阅读