#javascript #reactjs
#javascript #reactjs
Вопрос:
У меня есть приложение react, для которого я пытаюсь показать среднюю зарплату для каждого сотрудника, которую я получаю из своего файла data.json. Я могу вывести все зарплаты, но не уверен, как получить среднее значение всех зарплат на экране. Я довольно новичок в React, поэтому буду признателен за любую помощь.
import React,{useState,useEffect} from 'react';
import './App.css';
function App() {
const [data,setData]=useState([]);
const getData=()=>{
fetch('data.json'
,{
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
)
.then(function(response){
// console.log(response)
return response.json();
})
.then(function(myJson) {
setData(myJson)
});
}
useEffect(()=>{
getData()
},[])
const avg = () => {
return console.log(data);
}
return (
<div className="App">
{data amp;amp; data.length>0 amp;amp; data.map((item)=><p>{item.Salary}</p>)}
</div>
);
}
export default App;
Ответ №1:
Для этого вы можете использовать useMemo
хук. Это может выглядеть примерно так:
const avg = useMemo(() => {
if (data.length === 0) {
return 0;
}
return data.reduce((sum, item) => sum item.Salary, 0) / data.length;
}, [data])
Перехват memo получает массив зависимостей. В данном случае это так [data]
. Всякий раз, когда изменяется значение в массиве зависимостей, useMemo
перехват вычисляется повторно, и значение доступно через константу.
Комментарии:
1. Большое спасибо. Я попробовал это, и сначала он сказал, что «сумма» не определена. Я ввел sum в аргумент после useMemo, и теперь я возвращаю NaN.
2. Я исправил свой ответ, пожалуйста, взгляните на него еще раз и подумайте о том, чтобы пометить его как правильный ответ 🙂
3. Подробнее об этом можно прочитать
Array.reduce
здесь: developer.mozilla.org/de/docs/Web/JavaScript/Reference /… И подробнее оuseMemo
крючке здесь: reactjs.org/docs/hooks-reference.html#usememo4. По какой-то причине я все еще получаю NaN.
5. Вы убедились, что
item.Salary
это всегда допустимое число?
Ответ №2:
Вы же не хотите дублировать весь этот код каждый раз, когда вам нужно немного JSON в ваших компонентах. Вы можете начать с написания общего useAsync
пользовательского хука —
// hooks.js
import { useState, useEffect } from React
const useAsync = (runAsync, deps = []) => {
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [result, setResult] = useState(null)
useEffect(_ => {
Promise.resolve(runAsync(...deps))
.then(setResult, setError)
.finally(_ => setLoading(false))
}, deps)
return { loading, error, result }
}
export { useAsync }
Вы в восторге, поэтому сразу начинаете его использовать —
// MyComponent.js
import { useAsync } from "./hooks.js"
const MyComponent = () => {
const { loading, error, result:items } =
useAsync(_ => {
axios.get("path/to/json")
.then(res => res.json())
}, ...)
// ...
}
export default MyComponent
Но остановитесь на этом. Пишите больше полезных перехватов, когда они вам понадобятся —
// hooks.js (continued)
const useAysnc = //...
const fetchJson = (url) =>
fetch(url, {
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(r => r.json())
const useJson = (url) =>
useAsync(fetchJson, [url])
export { useAsync, useJson }
Теперь извлечь JSON в любом компоненте очень просто. Многократное использование универсальных функций снижает вероятность внесения ошибок в ваш собственный код. И вы получаете все возможные состояния: loading
, error
, или result
—
// MyComponent.js
import { useJson } from "./hooks.js"
const MyComponent = () => {
const { loading, error, result:items } =
useJson("path/to/json")
if (loading)
return <p>Loading...</p>
if (error)
return <p>Error: {error.message}</p>
return <div><Items items={items} /></div> // example use of `items`
}
export default MyComponent
Caclculating average
— это вопрос использования другой универсальной функции, sum
—
// stats.js
const average = a =>
sum(a) / a.length
const sum = a =>
a.reduce((s, v) => s v, 0)
export { average, sum }
Заметили закономерность? Изолируйте поведение и напишите повторно используемые функции. Импортируйте их там, где это необходимо. Вот как мы используем average
в вашем компоненте —
// MyComponent.js
import { average } from "./stats.js"
import { useJson } from "./hooks.js"
const MyComponent = () => {
// useJson...
<div>Average: {average(items.map(v => v.Salary))}</div>
}
export default MyComponent
Ответ №3:
Вам нужно найти сумму всех зарплат, а затем найти ее среднее значение.
let salaries=[2,3,8,1];
let sum=0;
for(let i=0;i<salaries.length;i ){
sum=sum salaries[i];
}
average=sum/salaries.length;
console.log(average);
Комментарии:
1. Это даст
Infinity
результат, если длина равна нулю. Кроме того, я думаю, что это не отвечает на вопрос, поскольку вопрос был скорее о том, как это сделать в react и, следовательно, в результате измененияdata
состояния.