Я создаю простое приложение Todo, я использую componentDidMount для отображения данных из базы данных. Но проблема в том, что как только я добавляю новые данные, данные сохраняются, но не отображаются на странице, пока я не обновлю их.
Затем я наткнулся на componentDidUpdate. Он работает отлично, но перерисовывается несколько раз. Я имею в виду, что он продолжает запрашивать сервер для проверки новых данных. Я использую Express для серверной части
Так может ли кто-нибудь сказать мне, как предотвратить это? или если есть лучшее решение?
Вот текущий код:
class Navbar extends Component {
state = {
userArray: [],
username: "",
email: ""
};
//Storing the Data
addBtn = e => {
e.preventDefault();
var data = {
username: this.state.username,
email: this.state.email
};
fetch("/user", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
})
.then(response => {
if (response.status >= 400) {
throw new Error("Bad response from server");
}
return response.json();
})
.then(data => {
console.info(data);
if (data === "success") {
console.info("Yay");
}
})
.catch(err => {
console.info(err);
});
console.info(this.state.userArray);
};
componentDidMount() {
this.displayData();
}
componentWillUpdate() {
this.displayData();
}
//Отображение данных
displayData() {
fetch("/user")
.then(data => data.json())
.then(data => {
this.setState({
userArray: data
});
});
}
//Handling the input values
logChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
Я пробовал это, но он все еще не показывает данные на экране.
Тогда вы не правильно сделали. Пожалуйста, добавьте свой метод render() и как и куда вы звонили setState.
Вы можете вызвать this.displayData() при успешном обратном вызове метода fetch call in addBtn.



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


Для этого нужно сначала понять, как работают componentDidMount и componentWillUpdate в React. Они методы жизненного цикла реакции.
componentDidMount вызывается после монтирования компонента. Он вызывается только один раз и никогда не вызывается снова, если его не размонтировать и не смонтировать снова.
componentWillUpdate вызывается каждый раз, когда изменяется состояние и происходит повторный рендеринг.
Как прокомментировал @trixn: Вам нужно вызвать this.setState() в addBtn, когда у вас есть данные, вместо многократного вызова this.displayData()
Итак, мне следует размонтировать, а затем снова смонтировать?
componentDidMount — это правильное место для загрузки в первый раз, а затем, после создания нового Todo, вам нужно обновить список сразу после завершения запроса СООБЩЕНИЕ.
.then(data => {
console.info(data);
if (data === "success") {
console.info("Yay");
this.displayData();
}
})
Чтобы улучшить производительность, вы должны вернуть новую запись Todo после POST, поэтому вы только помещаете ее в список userArray в состоянии, нет необходимости снова получать весь список
Очень ценю
Итак, давайте попробуем разобраться, почему обращений к серверу было много.
Когда создается componentDidMount, вы вызываете displayData, который затем устанавливает состояние. Как только вызывается setstate, он вызывает componentDidUpdate, который снова вызывает displayData, который затем вызывает setState. И цикл продолжается (вероятно, пока у вас не закончится память).
Вы можете попробовать этот класс:
import React from 'react';
export default class Navbar extends React.Component {
state = {
userArray: [],
username: '',
email: ''
};
componentDidMount() {
this.displayData();
}
addBtn = e => {
e.preventDefault();
var data = {
username: this.state.username,
email: this.state.email
};
fetch('/user', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
.then(response => {
if (response.status >= 400) {
throw new Error('Bad response from server');
}
return response.json();
})
.then(data => {
console.info(data);
if (data === 'success') {
this.displayData();
}
})
.catch(err => {
console.info(err);
});
};
displayData() {
fetch('/user')
.then(data => data.json())
.then(data => {
this.setState({
userArray: data
});
});
}
}
По сути, я удалил вызов displayData в componentDidUpdate, а затем вызвал displayData, когда вызов ApI был успешным.
Все дали правильный ответ, Но есть малюсенькая ошибка.
Вы должны вызвать displayData() вне if condition
.then(data => {
console.info(data);
if (data === "success") {
console.info("Yay");
}
this.displayData();
})
Вам нужно вызвать
this.setState()вaddBtn, когда у вас есть данные, вместо повторного вызоваthis.displayData(). Обновление состояния с помощьюsetStateвызовет повторный рендеринг. В настоящее время вы планируете новое обновление во время обновления, что приведет к бесконечному циклу обновлений. Также обратите внимание, чтоcomponentWillUpdateустарела и больше не должны использоваться.