Поэтому, когда я нахожусь на странице книги и нажимаю кнопку, чтобы удалить ее, она должна перенаправляться в мой профиль пользователя и удалять книгу из базы данных. Но происходит то, что ComponentWillMount снова вызывается для книги и не может ее найти. Может быть, у меня нет четкого понимания этих методов жизненного цикла, но я думал, что ComponentWillMount будет вызываться только один раз при первом рендеринге? Также использую Firebase для базы данных.
Вот соответствующий код (где Book == WIP):
WIP.js
componentWillMount() {
this.WIPRef.on('value', snapshot => {
let WIP = snapshot.val()
this.setState({
title: WIP.title ? WIP.title : "",
wordCount: WIP.wc ? WIP.wc : "",
logline: WIP.logline ? WIP.logline : "",
draft: WIP.draft ? WIP.draft : "",
language: WIP.language ? WIP.language : "",
disclaimers: WIP.disclaimers ? WIP.disclaimers : "",
improvementAreas: WIP.improvementAreas ? WIP.improvementAreas : "",
blurb: WIP.blurb ? WIP.blurb : "",
additionalNotes: WIP.additionalNotes ? WIP.additionalNotes : "",
writer: WIP.writer ? WIP.writer : "",
genres: WIP.genres ? WIP.genres : [],
types: WIP.types ? WIP.types : []
});
var promises = []
var writerRef = firebaseDB.database().ref(`/Users/${WIP.writer}`)
promises.push(writerRef.once('value'));
Promise.all(promises).then((snapshots) => {
snapshots.forEach((snapshot) => {
var writer = snapshot.val()
this.setState({
writerName: writer.displayName ? writer.displayName : ""
})
})
})
})
}
removeWIP(WIPId) {
this.setState({ redirect: true })
const usersWIPRef = firebaseDB.database().ref(`/Users/${this.state.writer}/WIPs/${this.state.wipId}`)
this.deleteWIPIndexRecord(this.state.wipId)
usersWIPRef.remove();
this.WIPRef.remove();
}
deleteWIPIndexRecord(wipId) {
const WIPRef = firebaseDB.database().ref(`WIPs/${wipId}`);
WIPRef.on('value', snapshot => {
// Get Algolia's objectID from the Firebase object key
const objectID = snapshot.key;
// Remove the object from Algolia
wipsIndex
.deleteObject(objectID)
.then(() => {
console.info('Firebase object deleted from Algolia', objectID);
})
.catch(error => {
console.error('Error when deleting contact from Algolia', error);
process.exit(1);
});
})
}
render() {
if (this.state.redirect === true) {
return <Redirect to= {{pathname: '/user/' + this.state.writer}} />
}
return(
<Button className = "black-bordered-button"
onClick = {() => this.removeWIP(WIP.id)}
>
Remove Item
</Button>
)
}
Но затем, когда я удаляю книгу, я получаю эту ошибку:
Uncaught TypeError: Cannot read property 'title' of null из этой строки в ComponentWillMounttitle: WIP.title ? WIP.title : ""
Вы можете предоставить весь код компонента? Меня особенно интересует конфигурация. Мне интересно, обновляется ли какой-либо элемент состояния, связанный с этим удаленным элементом, где-то, вызывая рендеринг этого компонента или компонентов выше.
Отредактировано, чтобы добавить более актуальный код. Вот ссылка на весь код компонента: github.com/mayaah/critique-connect/blob/master/src/components/…
Я думаю, что это не компонентWillMount, а ваш слушатель on.value.. может быть, вам следует отключить слушателя в вашем компоненте willunmount? это хорошая ссылка из самой firebase: firebase.google.com/docs/database/admin/…
Примитивный, но самый простой способ проверки — использовать alert в componentWillMount() перед слушателем. Предупреждение запускается один раз или несколько раз?
Да, я думал, что сделал this.WIPRef.off(); в моем componentWillUnmount :/ Оповещение вообще не запускается, когда я удаляю книгу/НЗП, что странно, потому что оно попадает в componentWillMount при отладке в консоли. И когда я добавляю this.WIPRef.off(); к моей функции removeWIP, она все равно выдает ту же ошибку.
Хорошо, я мог бы наложить на него пластырь, установив нулевую проверку WIP в componentWillMount, и если это не нулевое значение, то установить состояние. Но не знаю, если это лучшее решение.
Я бы предпочел использовать внутри constructor вместо componentWillMount .



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


можешь показать код режима где
delete actionвызывается