#reactjs #charts
Вопрос:
Диаграмма, созданная с использованием react-chartjs-2 и chartjs, обновляется 2 раза при изменении значений. В первый раз меняется только форма графика, а во второй раз меняются значения по осям y и x.
const Chart = ({country}) => {
const [dailyData,setDailyData] = useState([]);
useEffect(() => {
const fetchAPI = async () => {
setDailyData(await fetchDailyData(country))
}
fetchAPI();
},[country]);
const {day,infected,recoveries,deaths} = dailyData;
const lineChart = (
infected? (<Line
data={{
labels: day.map((data ) => (data)),
datasets:[
{
data: infected.map((data) => (data)),
label: 'Infected',
borderColor: '#3333ff',
fill: true,
}],
}}
/> ) : null
)
Комментарии:
1. почему вы помещаете определение fetchAPI в useEffect?
2. Возможно, вы захотите попробовать изменить useEffect для useLayoutEffect, чтобы предотвратить асинхронное рисование React.
3. @AnoopJoshi, помещающий fetchAPI в useEffect, — это способ предотвратить реакцию на то, чтобы кричать на вас за то, что вы не помещаете «fetchAPI» в зависимости от эффекта использования. Что, если вы действительно выведете fetchAPI наружу и добавите его в качестве зависимости от эффекта использования, вы получите бесконечный цикл. Что вам придется исправить, обернув fetchAPI крючком useCallback и т. Д., В любом случае, это не так уж плохо.
4. @BaltasarSolanilla Я попытался использовать useLayoutEffect, но все равно столкнулся с той же проблемой.
5. Извините, я мало что могу с этим поделать. Я бы рекомендовал вам создать песочницу с минимальным воспроизводимым примером, это не слишком много кода, должно быть легко. Может быть, кто-то еще заметит эту проблему.
Ответ №1:
Есть проблема с вашим dailyData
государством. Вы задаете значение по умолчанию в виде пустого массива, но затем пытаетесь уничтожить его как объект.
const asd=[1,2,4,5];
const {a,b,c}=asd;
console.log (a,b,c); // undefined, undefined, undefined
const [e,f,g]=asd;
console.log (e,f,g); // 1,2,4
Однако вы сказали, что ваша диаграмма работает после второй вспышки. Это означает, что ваш исходный пустой массив не является правильным значением по умолчанию для useState
крючка. Следует использовать null
и проверить это, прежде чем разрушать его.
ОБНОВЛЕНИЕ: Диаграмма может мигать дважды, если данные также загружаются дважды. useEffect
должен быть оператор if, проверяющий, были ли данные уже загружены, и загружайте только в том случае, если это не так. Возможно, вы могли бы добавить другое состояние для загрузки. таким образом, у вас не будет двух одновременных вызовов API.
Ваш код будет выглядеть следующим образом:
const Chart = ({country}) => {
const [dailyData,setDailyData] = useState(null);
useEffect(() => {
if(country amp;amp; !dailyData){
const fetchAPI = async () => {
setDailyData(await fetchDailyData(country))
}
fetchAPI();
}
},[country]);
let lineChart=null
if (dailyData){
const {day,infected,recoveries,deaths} = dailyData;
lineChart = (<Line
data={{
labels: day.map((data ) => (data)),
datasets:[
{
data: infected.map((data) => (data)),
label: 'Infected',
borderColor: '#3333ff',
fill: true,
}],
}}
/> )
}
}
Комментарии:
1. Спасибо за ответ, но он все равно освежает дважды.
2. Но теперь он показывает данные первой выбранной страны. Может быть, это не подходит для других из-за ! Состояние ежедневных данных.
3. Вы можете проверить, относятся ли текущие загруженные данные к текущей стране. Если это не так, то загрузите его для текущей страны. Это должно быть в том же состоянии, где ! Ежедневные данные есть.