Я прочитал много постов, но это мой первый вопрос!Позвольте мне сначала поблагодарить всех за поддержку и предложить описание проблемы перед длинным блоком кода!Любая помощь приветствуется ... Я думаю, что я близок!
ВОПРОС / ПРОБЛЕМА: мой метод setState работает только при начальной выборке данных.Последующие попытки извлекают новые данные, но не сбрасывают состояние, и, следовательно, дочерний компонент не получает новые реквизиты!
WHY / WHAT: я использую papa-анализ для извлечения данных CSV и их преобразованияв JSON, а затем передать эти данные ребенку.Я использую библиотеку карт D3 под названием реагировать-простые-карты, а затем вызываю анимации с помощью GSAP / Greensock.
При анализе папы по умолчанию используется обратный вызов вместо обещания (хотя обещания возможны), поэтому ясоздал метод _.isMounting, который я могу переключать ... причина в том, что после извлечения асинхронных данных мои анимации больше не запускаются в компоненте child / map, поскольку они вызываются в componentDidMount до завершения выборки!теперь мое исправление работает, но не будет работать снова и снова!Я буду передавать новые данные, чтобы создавать наборы маркеров карты несколько раз и час!Смотрите мой комментарий ниже!
class MapContainerParent extends Component {
_isMounted = false; //toggling this allows the child component to wait for data fetch to complete before render
_isRefreshed = false; //tried, but not working?
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true,
error: null
};
this.updateData = this.updateData.bind(this);
}
//I'm using papaparse to fetch and convert the csv file to JSON
//it uses a callback instead of a promise, which may be the issue?
fetchAndConvert() {
//Papa Parse to convert CSV to JSON...also fetches from S3 bucket
const Papa = require("papaparse");
const dataFilePath =
"url of where the csv file lives";
Papa.parse(dataFilePath, {
download: true,
header: false,
skipEmptyLines: true,
complete: this.updateData //callback, which sets the state after the data is in proper format
});
}
//HEre is the callback
updateData(result) {
const data = result.data;
const mapData = data.map(item => {.....
//takes the resulting json and formats it
console.log("MapData restructured:", mapData);
if (this._isMounted) { //I THINK THE PROBLEM IS HERE!
this.setState({ //Only sets the state on initial render!
//makes sense since I have told it to setState when isMounted is true.
//Since I'm fetching new data several times an hour, this won't do!
//How can I add another condition to reset state when new data is present?
data: mapData,
isLoading: false,
error: false
});
} //tried to add an _isRefreshed condition, not working?
else if (this._isMounted && this._isRefreshed === false) {
this.setState({
data: mapData,
isLoading: false,
error: false
});
}
}
componentDidMount() {
this._isMounted = true;
this.fetchAndConvert();
this._isRefreshed = true; //dn work
setInterval(this.fetchAndConvert, 30000);
//runs the function at an interval I set
//I see the new data when I preview the network request
//but it does not trigger a new setState???
}
componentWillUnmount() {
this._isMounted = false;
this._isRefreshed = false; //not working...
}
renderLoading() {
return <div > loading... < /div>;
}
renderError() {
return <div > Error... < /div>;
}
renderMap() {
return (
<div>
<MapChild data = {this.state.data/> <
</div>
);
}
render() {
if (this.state.loading) {
return this.renderLoading();
} else if (this.state.data.length > 0) {
return this.renderMap();
} else {
return this.renderError();
}
}
}
export default MapContainerParent;