首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >生命周期钩子-在哪里设置状态?

生命周期钩子-在哪里设置状态?
EN

Stack Overflow用户
提问于 2018-11-03 07:06:34
回答 1查看 160关注 0票数 0

我正在尝试将排序添加到我的电影应用程序中,我有一个运行良好的代码,但有太多的代码重复,我想采取不同的方法,并保持我的代码干燥。无论如何,我都很困惑,当我调用AJAX并用click事件更新它时,应该使用哪种方法来设置状态。

这是一个模块,用于获取我的应用程序所需的数据。

代码语言:javascript
复制
export const moviesData = {
  popular_movies: [],
  top_movies: [],
  theaters_movies: []
};

export const queries = {
  popular:
    "https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=###&page=",
  top_rated:
    "https://api.themoviedb.org/3/movie/top_rated?api_key=###&page=",
  theaters:
    "https://api.themoviedb.org/3/movie/now_playing?api_key=###&page="
};

export const key = "68f7e49d39fd0c0a1dd9bd094d9a8c75";

export function getData(arr, str) {
  for (let i = 1; i < 11; i++) {
    moviesData[arr].push(str + i);
  }
}

有状态组件:

代码语言:javascript
复制
class App extends Component {
  state = { 
   movies = [],
   sortMovies: "popular_movies",
   query: queries.popular,
   sortValue: "Popularity"
  }
}

// Here I am making the http request, documentation says
// this is a good place to load data from an end point
async componentDidMount() {
    const { sortMovies, query } = this.state;
    getData(sortMovies, query);

    const data = await Promise.all(
      moviesData[sortMovies].map(async movie => await axios.get(movie))
    );
    const movies = [].concat.apply([], data.map(movie => movie.data.results));

    this.setState({ movies });
  }

在我的应用程序中,我有一个下拉菜单,你可以在其中按人气、评分等对电影进行排序。我有一个方法,当我从下拉菜单中选择一个选项时,我会更新一些状态属性:

代码语言:javascript
复制
handleSortValue = value => {
    let { sortMovies, query } = this.state;

    if (value === "Top Rated") {
      sortMovies = "top_movies";
      query = queries.top_rated;
    } else if (value === "Now Playing") {
      sortMovies = "theaters_movies";
      query = queries.theaters;
    } else {
      sortMovies = "popular_movies";
      query = queries.popular;
    }

    this.setState({ sortMovies, query, sortValue: value });
  };

现在,这个方法起作用了,它正在更改状态中的属性,但我的组件不会重新呈现。我仍然可以看到按人气排序的电影,因为这是状态(sortMovies)中的原始设置,没有任何更新。

我知道这是因为我在componentDidMount方法中设置了电影的状态,但我需要在默认情况下初始化数据,所以我不知道如果不是在这个方法中,我还应该在哪里执行此操作。

我希望我已经说清楚了我在这里要做什么,如果没有,请问我,我被困在这里了,任何帮助都是非常感谢的。提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2018-11-03 08:50:21

获取数据的最佳生命周期方法是componentDidMount()。根据React docs的说法

在组件生命周期中的哪个位置应该进行AJAX调用?

您应该在componentDidMount()生命周期方法中使用AJAX调用来填充数据。这是为了在检索数据时使用setState()更新组件。

文档中的示例代码:

代码语言:javascript
复制
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      items: []
    };
  }

  componentDidMount() {
    fetch("https://api.example.com/items")
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            items: result.items
          });
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {
    const { error, isLoaded, items } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <ul>
          {items.map(item => (
            <li key={item.name}>
              {item.name} {item.price}
            </li>
          ))}
        </ul>
      );
    }
  }
}

奖励: setState() inside componentDidMount()被认为是一种反模式。只有在获取数据/测量DOM节点时才使用此模式。进一步阅读:

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53126825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档