#reactjs #wordpress
#reactjs #wordpress
Вопрос:
Я не могу понять, почему моя функция renderMovies () не хочет обновлять состояние моего компонента.данные, и я не могу отобразить компонент на моем экране ?! Все идет нормально, пока renderMovies не заработает.. Я думаю, что this.setState(newState) в моей функции fetchPostData работает неправильно… Кто-нибудь знает, как это исправить? Я пробовал разные способы, но не могу решить эту проблему.
class Movies extends React.Component {
constructor(props) {
super(props)
this.state = { data: {}}
this.fetchPostData = this.fetchPostData.bind(this)
this.renderMovies = this.renderMovies.bind(this)
this.populatePageAfterFetch = this.populatePageAfterFetch.bind(this)
}
componentDidMount() {
this.fetchPostData()
}
fetchPostData() {
fetch(`http://localhost/reacttest/wp-json/wp/v2/movies?per_page=100`)
.then(response => response.json())
.then(myJSON => {
let objLength = Object.keys(myJSON).length
let newState = this.state;
for (let i = 0; i < objLength; i ) {
let objKey = Object.values(myJSON)[i].title.rendered;
// console.log(objKey)
let currentMovie = newState.data[objKey];
currentMovie = {};
currentMovie.name = Object.values(myJSON)[i].title.rendered;
currentMovie.description = Object.values(myJSON)[i].content.rendered;
currentMovie.featured_image = Object.values(myJSON)[i]['featured_image_url'];
currentMovie.genre = Object.values(myJSON)[i]['genre'];
}
this.setState(newState)
})
}
renderMovies() {
if(this.state.data) {
const moviesArray = Object.values(this.state.data)
console.log(moviesArray)
return Object.values(moviesArray).map((movie, index) => this.populatePageAfterFetch(movie, index))
}
}
populatePageAfterFetch(movie, index) {
if (this.state.data) {
return (
<div key={index} index={index}>
<h2>{movie.title}</h2>
<h3>{movie.genre}</h3>
<p>{movie.description}</p>
</div>
)
}
}
render() {
return (
<div>
<h1>Movies</h1>
<div>{this.renderMovies()}</div>
</div>
)
}
}
Когда я пытаюсь console.log (moviesArray), он показывает мне:
Комментарии:
1. получаете ли вы значения, если регистрируете ‘newState’ непосредственно перед строкой ‘this.setState (newState)’?
Ответ №1:
Проблема
Вы сохраняете текущее состояние в переменной с именем newState
, никогда не обновляете ее, а затем сохраняете ту же ссылку на объект обратно в состояние. Состояние реакции никогда не обновляется.
let newState = this.state;
for (let i = 0; i < objLength; i ) {
...
}
this.setState(newState);
Кроме того, вы изменяете состояние
let currentMovie = newState.data[objKey];
currentMovie = {};
Но это тоже не работает, поскольку начальное состояние является пустым объектом, поэтому newState.data[objKey]
всегда не определено. (так что на самом деле ничего не меняется)
Решение
Похоже, что вы намеревались сопоставить myJSON
данные / значения с объектами movie для обновления this.state.data
. Могу ли я предложить это решение. Ключ в том, чтобы всегда создавать новые ссылки на объекты для любого объекта, который вы обновляете.
fetchPostData() {
fetch(`http://localhost/reacttest/wp-json/wp/v2/movies?per_page=100`)
.then(response => response.json())
.then(myJSON => {
this.setState(prevState => ({
// array::reduce over the JSON values
data: Object.values(myJSON).reduce((movies, movie) => {
// compute movie key
const name = movie.title.rendered;
return {
...movies,
[name]: {
...movies[name], // copy any existing movie properties
// merge in new/updated properties
name,
description: movie.content.rendered,
featured_image: movie.featured_image_url,
genre: movie.genre,
},
}
}, { ...prevState.data }) // use previous state as initial value for reduce
}))
})
}