Вы видите неправильное значение, потому что вы устанавливаете e.target.innerText
до того, как axios.post
будет выполнено. Вы можете переместить этот код в функцию обратного вызова, чтобы получить желаемый порядок операций, например, такой:
handleLike = (url, e) => {
if (e.target.innerText.toLowerCase() === "like"){
axios.post('/api/showengagement', {url: url})
.then(res => {
e.target.innerText = `This post has ${res.data.likes} like(s)`
});
axios.post('/api/incrementlikes', {url: url});
}
else{
e.target.innerText = "Like";
axios.post('/api/decrementlikes', {url: url});
}
}
Делая это таким образом, вам даже не нужно сохранять значение в state
. Вы все еще можете сделать это, если это необходимо в другом месте кода.
Причина, по которой вы установили innerText
, произошла до того, как значение вернулось, заключается в том, что axios.post
является асинхронным и возвращается до завершения операциии ваша функция переходит к следующей строке (установка текста на старое значение). Новое значение появляется позже, когда post
завершается и вызывается ваша функция обратного вызова.
Еще лучше: избегайте использования innerText - используйте render ()
Другой способ сделать это - это иметьВаша функция render()
отвечает за запись значения в соответствующем месте с использованием переменной state
. Когда вы вызываете this.setState()
, это вызывает повторную визуализацию компонента, и вы увидите, что значение появляется. Вот рабочий класс React, который показывает это:
import React from "react";
let likes = [];
let urls = ["url1", "url2"];
class Sample extends React.Component {
constructor(props) {
super(props);
this.state = { likeEngages: [] }; // initialize the array of likeEngages
}
// fake implementation of 'post' instead of axios.post
post = (url, body) => {
if (!likes[body.id]) likes[body.id] = 1;
if (url === "/api/showengagement") {
return Promise.resolve({ data: { likes: likes[body.id] } });
} else {
likes[body.id]++; // increment Likes for given id
return Promise.resolve();
}
};
handleLike = (url, e) => {
const id = e.target.id;
this.post("/api/showengagement", { url, id }).then(res => {
const engages = this.state.likeEngages;
engages[id] = res.data.likes; // set the likes count in the state
this.setState({ likeEngages: engages });
});
this.post("/api/incrementlikes", { url, id });
};
showLikes = id => {
if (this.state.likeEngages[id])
return (
<span>
{" This post has " + this.state.likeEngages[id] + " like(s)"}
</span>
);
return " No likes yet";
};
render() {
return (
<div>
<ul>
<li>
<button id="id1" onClick={e => this.handleLike(urls[0], e)}>
Like1
</button>
{this.showLikes("id1")}
</li>
<li>
<button id="id2" onClick={e => this.handleLike(urls[1], e)}>
Like2
</button>
{this.showLikes("id2")}
</li>
</ul>
</div>
);
}
}
export default Sample;