【问题标题】:Lifecycle hooks - Where to set state?生命周期挂钩 - 在哪里设置状态?
【发布时间】:2018-11-02 23:06:34
【问题描述】:

我正在尝试向我的电影应用程序添加排序,我的代码运行良好,但代码重复过多,我想采用不同的方法并保持我的代码 DRY。无论如何,当我进行 AJAX 调用并使用单击事件更新它时,我对应该设置状态的方法感到困惑。

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

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

有状态组件:

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

在我的应用程序中,我有一个下拉菜单,您可以在其中按受欢迎程度、评级等对电影进行排序。我有一种方法,当我从下拉列表中选择一个选项时,我会更新一些状态属性:

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 方法中设置了电影的状态,但我需要默认初始化数据,所以如果不是在此方法中,我不知道我应该在哪里执行此操作。

我希望我清楚自己要在这里做什么,如果不是,请询问,我被困在这里,非常感谢任何帮助。提前致谢。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

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

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

    您应该在 componentDidMount() 生命周期方法中使用 AJAX 调用填充数据。这样您就可以在检索数据时使用setState() 更新您的组件。

    文档中的示例代码:

    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()componentDidMount() 被视为反模式。仅在获取数据/测量 DOM 节点时使用此模式。 延伸阅读:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 2018-06-30
      • 1970-01-01
      • 2017-01-18
      • 2018-08-28
      • 2021-10-27
      相关资源
      最近更新 更多