为什么在第二次调用后componentDidMount方法不起作用?

时间:2019-10-10 15:38:57

标签: reactjs

我想根据URL参数更改组件显示的内容,但同时要使用相同的组件。当我执行我的代码时,第一次调用componentDidMount,但是第二次之后不起作用。结果,我无法更改组件显示的内容。

我正在使用react.js。 尽管我使用componentDidUpdate而不是componentDidMount,但它导致了无限循环。

import React from "react";
import ReactMarkdown from "react-markdown";
import Contentful from "./Contentful";
import "./Article.css";

class ArticlesWithTag extends React.Component {
  state = {
    articleFromContentful: []
  };

  async componentDidMount() {
    console.log("componentDidMount");
    const { tag } = this.props.match.params;
    //get article from contentful API
    const contentful = new Contentful();
    try {
      const article = await contentful.getArtcleWithTags(
        undefined,
        "blogPost",
        tag
      );
      this.setState({ articleFromContentful: article.items });
    } catch (err) {
      console.log("error");
      console.log(err);
    }
  }


  render() {
    const bodyOfArticle = this.state.articleFromContentful.map(data => {
      const returnTitle = () => {
        return data.fields.title;
      };

      const returnPublishedDate = () => {
        let date = data.fields.publishDate.substring(0, 10);
        let replacedDate = date.replace("-", "/");

        while (date !== replacedDate) {
          date = date.replace("-", "/");
          replacedDate = replacedDate.replace("-", "/");
        }
        return replacedDate;
      };

      const returnBody = () => {
        return data.fields.body;
      };

      const returnTags = () => {
        const tagList = data.fields.tags.map(data => {
          const listContent = `#${data}`;
          return <li>{listContent}</li>;
        });
        return tagList;
      };

      returnTags();
      return (
        <div className="article-container">
          <div className="article-title">{returnTitle()}</div>
          <p className="article-date">{returnPublishedDate()}</p>
          <div className="article-body">
            <ReactMarkdown source={returnBody()}></ReactMarkdown>
          </div>
          <div className="article-tags">
            <ul>{returnTags()}</ul>
          </div>
        </div>
      );
    });

    return <div className="article-outer">{bodyOfArticle}</div>;
  }
}

export default ArticlesWithTag;

3 个答案:

答案 0 :(得分:0)

componentDidMount仅在安装组件时被调用。 道具更改后,将调用componentDidUpdate。 您应该使用componentDidMount逻辑创建一个函数,并仅在标记发生更改时才在componentDidUpdate中调用

答案 1 :(得分:0)

componentDidMount()仅在组件最初安装到DOM时调用。由prop或状态更改引起的重新渲染将触发componentDidUpdate()。如您所述,在此函数中进行状态更改会导致无限循环。

您可以做的是使用componentDidUpdate()并在决定再次更新状态之前检查道具是否已更改。这样可以避免出现无限循环情况。

答案 2 :(得分:0)

确定 componentDidMount 是仅在安装组件时运行的lifecylce方法 并且 componentDidUpdate 会在每次有更新时运行

您可以在componentDidUpdate中设置状态,但必须将其包装在某些条件下 根据您的情况,您可以执行以下操作

 async componentDidMount() {
console.log("componentDidMount");
const { tag } = this.props.match.params;
//get article from contentful API
const contentful = new Contentful();
try {
  const article = await contentful.getArtcleWithTags(
    undefined,
    "blogPost",
    tag
  );
  this.setState({ articleFromContentful: article.items });
} catch (err) {
  console.log("error");
  console.log(err);
}
}

,要进行进一步更新,请使用compnentDidUpdate作为

 async componentDidUpdate(prevProps) {
const { tag } = this.props.match.params;
//get article from contentful API
const contentful = new Contentful();
if ( tag !== prevProps.match.params ) // if props have changed
{
try {
  const article = await contentful.getArtcleWithTags(
    undefined,
    "blogPost",
    tag
  );
  this.setState({ articleFromContentful: article.items });
} catch (err) {
  console.log("error");
  console.log(err);
}
}
}

希望有帮助