Получение среднего значения из JSON в React

#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#usememo

4. По какой-то причине я все еще получаю 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 состояния.