状态正在更新但未呈现
The states is updating but not rendering
当我想点击恢复或死亡时,我想改变圆圈的颜色。当我感到安慰时,状态值已更新但圆圈颜色没有改变。下面是代码和图片。我尝试了我所知道的一切,但没有奏效。为什么我的状态不将新值识别为新值而不触发刷新?有帮助吗?
Issue
import React, { useState, useEffect } from "react";
import "./App.css";
import {
MenuItem,
FormControl,
Select,
Card,
CardContent,
} from "@material-ui/core";
import InfoBox from "../src/InfoBox/InfoBox";
import LineGraph from "../src/LineGraph/LineGraph";
import Table from "../src/Table/Table";
import { sortData, prettyPrintStat } from "./util";
import numeral from "numeral";
import CovidMap from "../src/Map/CovidMap";
import "leaflet/dist/leaflet.css";
const App = () => {
const [country, setInputCountry] = useState("worldwide");
const [countryInfo, setCountryInfo] = useState({});
const [countries, setCountries] = useState([]);
const [mapCountries, setMapCountries] = useState([]);
const [tableData, setTableData] = useState([]);
const [casesType, setCasesType] = useState("cases");
const [mapCenter, setMapCenter] = useState([34, -40]);
const [mapZoom, setMapZoom] = useState(3);
useEffect(() => {
fetch("https://disease.sh/v3/covid-19/all")
.then((response) => response.json())
.then((data) => {
setCountryInfo(data);
});
}, []);
useEffect(() => {
const getCountriesData = async () => {
fetch("https://disease.sh/v3/covid-19/countries")
.then((response) => response.json())
.then((data) => {
const countries = data.map((country) => ({
name: country.country,
value: country.countryInfo.iso2,
}));
let sortedData = sortData(data);
setCountries(countries);
setMapCountries(data);
setTableData(sortedData);
});
};
getCountriesData();
}, []);
console.log(casesType);
const onCountryChange = async (e) => {
const countryCode = e.target.value;
const url =
countryCode === "worldwide"
? "https://disease.sh/v3/covid-19/all"
: `https://disease.sh/v3/covid-19/countries/${countryCode}`;
await fetch(url)
.then((response) => response.json())
.then((data) => {
setInputCountry(countryCode);
setCountryInfo(data);
setMapCenter([data.countryInfo.lat, data.countryInfo.long]);
setMapZoom(4);
});
};
return (
<div className="app">
<div className="left">
<div className="header">
<h1>Caner Demir COVID Tracker</h1>
<FormControl className="dropdown">
<Select
variant="outlined"
value={country}
onChange={onCountryChange}
>
<MenuItem value="worldwide">Worldwide</MenuItem>
{countries.map((country) => (
<MenuItem value={country.value}>{country.name}</MenuItem>
))}
</Select>
</FormControl>
</div>
<div className="stats">
<InfoBox
onClick={(e) => setCasesType("cases")}
title="Coronavirus Cases"
isRed
active={casesType === "cases"}
cases={prettyPrintStat(countryInfo.todayCases)}
total={numeral(countryInfo.cases).format("0.0a")}
/>
<InfoBox
onClick={(e) => setCasesType("recovered")}
title="Recovered"
active={casesType === "recovered"}
cases={prettyPrintStat(countryInfo.todayRecovered)}
total={numeral(countryInfo.recovered).format("0.0a")}
/>
<InfoBox
onClick={(e) => setCasesType("deaths")}
title="Deaths"
isRed
active={casesType === "deaths"}
cases={prettyPrintStat(countryInfo.todayDeaths)}
total={numeral(countryInfo.deaths).format("0.0a")}
/>
</div>
<CovidMap
countries={mapCountries}
casesType={casesType}
center={mapCenter}
zoom={mapZoom}
showDataOnMap
/>
</div>
<Card className="right">
<CardContent>
<div className="information">
<h3>Live Cases by Country</h3>
<Table countries={tableData} />
<h3>Worldwide new {casesType}</h3>
<LineGraph className="graph" casesType={casesType} />
</div>
</CardContent>
</Card>
</div>
);
};
export default App;
/**/
import React from "react";
import { MapContainer, TileLayer } from "react-leaflet";
import "./Map.css";
import numeral from "numeral";
import { Circle, Popup } from "react-leaflet";
export default function CovidMap({ countries, casesType, center, zoom }) {
const casesTypeColors = {
cases: {
hex: "#CC1034",
multiplier: 120,
},
recovered: {
hex: "#7DD71D",
multiplier: 100,
},
deaths: {
hex: "#FB4443",
multiplier: 300,
},
};
const showDataOnMap = (data, casesType) =>
data.map((country) => (
<Circle
center={[country.countryInfo.lat, country.countryInfo.long]}
color={casesTypeColors[casesType].hex}
fillColor={casesTypeColors[casesType].hex}
fillOpacity={0.4}
radius={
Math.sqrt(country[casesType]) * casesTypeColors[casesType].multiplier
}
>
<Popup>
<div className="info-container">
<div
className="info-flag"
style={{ backgroundImage: `url(${country.countryInfo.flag})` }}
></div>
<div className="info-name">{country.country}</div>
<div className="info-confirmed">
Cases: {numeral(country.cases).format("0,0")}
</div>
<div className="info-recovered">
Recovered: {numeral(country.recovered).format("0,0")}
</div>
<div className="info-deaths">
Deaths: {numeral(country.deaths).format("0,0")}
</div>
</div>
</Popup>
</Circle>
));
return (
<div className="map">
<MapContainer center={center} zoom={zoom}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{showDataOnMap(countries, casesType)}
</MapContainer>
</div>
);
}
根据 circle Leaflet documentation,color
、fillColor
和 fillOpacity
属性应在 pathOptions
中作为对象传递,而不是在元素的根级别。
将 <Circle />
组件属性更改为以下应该可以解决您的问题:
<Circle
center={[country.countryInfo.lat, country.countryInfo.long]}
pathOptions={{
color: casesTypeColors[casesType].hex,
fillColor: casesTypeColors[casesType].hex,
fillOpacity: 0.4
}}
radius={
Math.sqrt(country[casesType]) * casesTypeColors[casesType].multiplier
}
>
当我想点击恢复或死亡时,我想改变圆圈的颜色。当我感到安慰时,状态值已更新但圆圈颜色没有改变。下面是代码和图片。我尝试了我所知道的一切,但没有奏效。为什么我的状态不将新值识别为新值而不触发刷新?有帮助吗?
Issue
import React, { useState, useEffect } from "react";
import "./App.css";
import {
MenuItem,
FormControl,
Select,
Card,
CardContent,
} from "@material-ui/core";
import InfoBox from "../src/InfoBox/InfoBox";
import LineGraph from "../src/LineGraph/LineGraph";
import Table from "../src/Table/Table";
import { sortData, prettyPrintStat } from "./util";
import numeral from "numeral";
import CovidMap from "../src/Map/CovidMap";
import "leaflet/dist/leaflet.css";
const App = () => {
const [country, setInputCountry] = useState("worldwide");
const [countryInfo, setCountryInfo] = useState({});
const [countries, setCountries] = useState([]);
const [mapCountries, setMapCountries] = useState([]);
const [tableData, setTableData] = useState([]);
const [casesType, setCasesType] = useState("cases");
const [mapCenter, setMapCenter] = useState([34, -40]);
const [mapZoom, setMapZoom] = useState(3);
useEffect(() => {
fetch("https://disease.sh/v3/covid-19/all")
.then((response) => response.json())
.then((data) => {
setCountryInfo(data);
});
}, []);
useEffect(() => {
const getCountriesData = async () => {
fetch("https://disease.sh/v3/covid-19/countries")
.then((response) => response.json())
.then((data) => {
const countries = data.map((country) => ({
name: country.country,
value: country.countryInfo.iso2,
}));
let sortedData = sortData(data);
setCountries(countries);
setMapCountries(data);
setTableData(sortedData);
});
};
getCountriesData();
}, []);
console.log(casesType);
const onCountryChange = async (e) => {
const countryCode = e.target.value;
const url =
countryCode === "worldwide"
? "https://disease.sh/v3/covid-19/all"
: `https://disease.sh/v3/covid-19/countries/${countryCode}`;
await fetch(url)
.then((response) => response.json())
.then((data) => {
setInputCountry(countryCode);
setCountryInfo(data);
setMapCenter([data.countryInfo.lat, data.countryInfo.long]);
setMapZoom(4);
});
};
return (
<div className="app">
<div className="left">
<div className="header">
<h1>Caner Demir COVID Tracker</h1>
<FormControl className="dropdown">
<Select
variant="outlined"
value={country}
onChange={onCountryChange}
>
<MenuItem value="worldwide">Worldwide</MenuItem>
{countries.map((country) => (
<MenuItem value={country.value}>{country.name}</MenuItem>
))}
</Select>
</FormControl>
</div>
<div className="stats">
<InfoBox
onClick={(e) => setCasesType("cases")}
title="Coronavirus Cases"
isRed
active={casesType === "cases"}
cases={prettyPrintStat(countryInfo.todayCases)}
total={numeral(countryInfo.cases).format("0.0a")}
/>
<InfoBox
onClick={(e) => setCasesType("recovered")}
title="Recovered"
active={casesType === "recovered"}
cases={prettyPrintStat(countryInfo.todayRecovered)}
total={numeral(countryInfo.recovered).format("0.0a")}
/>
<InfoBox
onClick={(e) => setCasesType("deaths")}
title="Deaths"
isRed
active={casesType === "deaths"}
cases={prettyPrintStat(countryInfo.todayDeaths)}
total={numeral(countryInfo.deaths).format("0.0a")}
/>
</div>
<CovidMap
countries={mapCountries}
casesType={casesType}
center={mapCenter}
zoom={mapZoom}
showDataOnMap
/>
</div>
<Card className="right">
<CardContent>
<div className="information">
<h3>Live Cases by Country</h3>
<Table countries={tableData} />
<h3>Worldwide new {casesType}</h3>
<LineGraph className="graph" casesType={casesType} />
</div>
</CardContent>
</Card>
</div>
);
};
export default App;
/**/
import React from "react";
import { MapContainer, TileLayer } from "react-leaflet";
import "./Map.css";
import numeral from "numeral";
import { Circle, Popup } from "react-leaflet";
export default function CovidMap({ countries, casesType, center, zoom }) {
const casesTypeColors = {
cases: {
hex: "#CC1034",
multiplier: 120,
},
recovered: {
hex: "#7DD71D",
multiplier: 100,
},
deaths: {
hex: "#FB4443",
multiplier: 300,
},
};
const showDataOnMap = (data, casesType) =>
data.map((country) => (
<Circle
center={[country.countryInfo.lat, country.countryInfo.long]}
color={casesTypeColors[casesType].hex}
fillColor={casesTypeColors[casesType].hex}
fillOpacity={0.4}
radius={
Math.sqrt(country[casesType]) * casesTypeColors[casesType].multiplier
}
>
<Popup>
<div className="info-container">
<div
className="info-flag"
style={{ backgroundImage: `url(${country.countryInfo.flag})` }}
></div>
<div className="info-name">{country.country}</div>
<div className="info-confirmed">
Cases: {numeral(country.cases).format("0,0")}
</div>
<div className="info-recovered">
Recovered: {numeral(country.recovered).format("0,0")}
</div>
<div className="info-deaths">
Deaths: {numeral(country.deaths).format("0,0")}
</div>
</div>
</Popup>
</Circle>
));
return (
<div className="map">
<MapContainer center={center} zoom={zoom}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{showDataOnMap(countries, casesType)}
</MapContainer>
</div>
);
}
根据 circle Leaflet documentation,color
、fillColor
和 fillOpacity
属性应在 pathOptions
中作为对象传递,而不是在元素的根级别。
将 <Circle />
组件属性更改为以下应该可以解决您的问题:
<Circle
center={[country.countryInfo.lat, country.countryInfo.long]}
pathOptions={{
color: casesTypeColors[casesType].hex,
fillColor: casesTypeColors[casesType].hex,
fillOpacity: 0.4
}}
radius={
Math.sqrt(country[casesType]) * casesTypeColors[casesType].multiplier
}
>