我正在尝试将排序添加到我的电影应用程序中,我有一个运行良好的代码,但有太多的代码重复,我想采取不同的方法,并保持我的代码干燥。无论如何,我都很困惑,当我调用AJAX并用click事件更新它时,应该使用哪种方法来设置状态。
这是一个模块,用于获取我的应用程序所需的数据。
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方法中设置了电影的状态,但我需要在默认情况下初始化数据,所以我不知道如果不是在这个方法中,我还应该在哪里执行此操作。
我希望我已经说清楚了我在这里要做什么,如果没有,请问我,我被困在这里了,任何帮助都是非常感谢的。提前谢谢。
发布于 2018-11-03 08:50:21
获取数据的最佳生命周期方法是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() inside componentDidMount()被认为是一种反模式。只有在获取数据/测量DOM节点时才使用此模式。进一步阅读:
https://stackoverflow.com/questions/53126825
复制相似问题