ReactJS: вычислить среднее значение из массива строк в объекте JSON во время рендеринга

#json #reactjs

#json #reactjs

Вопрос:

Мое первое приложение с ReactJS

У меня нет предыдущего опыта работы с reactjs и json , но я пытаюсь повысить свой набор навыков, и мне сказали, что reactjs это отлично подходит для интерфейса.

Я пытаюсь прочитать вызов an API , получить json объект, проанализировать его и отобразить определенную информацию. Я могу достичь почти всего этого с относительной легкостью с помощью нескольких онлайн-руководств, но я уперся в стену.

Проблема:
я проанализировал и отобразил большую часть json объекта, но в каждом объекте есть array количество строк. Я хотел бы взять среднее значение этого array из json объекта и также отобразить его в html . Ниже приведена моя попытка:

 //importing necessary modules
import React from 'react';
import ReactDOM from 'react-dom';

//class creates the React component I am building
class ContentFeed extends React.Component {
   constructor() {
     super();

     this.state = {
       'workers': []
     }
   }

   componentDidMount() {
     this.getItems();
   }

   getItems() {
     fetch('localhost:7575')
       .then(results => results.json())
       //.then(results => console.log(results));
       .then(results => this.setState({'workers': results.workers}));
   }

   render() {
     return (            
       <ul>
         // I'm quite new to reactjs 
         // so I'm not too sure if what I'm doing below is legal syntax
         {this.state.workers.map(function(item, index) {
             var arrNum = 0;    
             var h = item.hours.split(",");
             var sum = 0;
             for(var i = 0; i < h.length; i  ) {
                sum  = parseInt(h[i]);
             }
             arrNum = (sum/h.length);    
             return (
                <div key={index}>
                  <h1>{item.firstName} {item.lastName}</h1>
                  <h4>{item.hireDate}</h4>
                  <h4>{item.dept}</h4>
                  <h4>arrNum</h4>
                </div>
              )
          })}
       </ul>
     );
   }
}

ReactDOM.render(
    <ContentFeed/>,
    document.getElementById('root')
);
  

Должна появиться html страница с заголовком, который содержит имя сотрудника, за которым следуют заголовки меньшего размера, содержащие соответствующую информацию о сотруднике, за которыми следует среднее значение их рабочего времени.

Однако веб-страница пуста.

Я проверил console вкладку в инструментах разработчика на странице и увидел ошибку, подобную этой:

 Uncaught TypeError: item.hours.split is not a function
    at index.js:29
    at Array.map (<anonymous>)
    at ContentFeed.render (index.js:26)
    at finishClassComponent (react-dom.development.js:17160)
    at updateClassComponent (react-dom.development.js:17110)
    at beginWork (react-dom.development.js:18620)
    at HTMLUnknownElement.callCallback (react-dom.development.js:188)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
    at invokeGuardedCallback (react-dom.development.js:292)
    at beginWork$1 (react-dom.development.js:23203)
  

Я не уверен, как это решить. Я искренне надеюсь, что предоставил столько релевантной информации, сколько было необходимо. Спасибо за любую помощь.

ОБНОВЛЕНИЕ 1

Это из вкладки консоли

 Uncaught TypeError: item.hours.split is not a function
    at index.js:29
    at Array.map (<anonymous>)
    at ContentFeed.render (index.js:26)
    at finishClassComponent (react-dom.development.js:17160)
    at updateClassComponent (react-dom.development.js:17110)
    at beginWork (react-dom.development.js:18620)
    at HTMLUnknownElement.callCallback (react-dom.development.js:188)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
    at invokeGuardedCallback (react-dom.development.js:292)
    at beginWork$1 (react-dom.development.js:23203)
  

ОБНОВЛЕНИЕ 2

Это часть необработанного JSON из выборки

 {
"workers": [
{
"firstName": "Tom",
"lastName": "Ronson",
"dept": "Sales",
"hireDate": "09/09/2015",
"hours": [
"8",
"10",
"4",
"6",
"6"
]
},
{
"firstName": "Bob",
"lastName": "Howser",
"dept": "Acct",
"hireDate": "01/05/2005",
"hours": [
"8",
"10",
"4",
"6",
"6"
]
},
{
"firstName": "Jane",
"lastName": "Winger",
"dept": "Legal",
"hireDate": "08/01/2008",
"hours": [
"5",
"6",
"5",
"5",
"6"
]
},
  

Комментарии:

1. вы уверены в данных, которые получаете с сервера?

2. да, я проверил это с помощью журнала консоли, а затем я также увидел обычный json с плагином chrome.

3.Можете ли вы обновить вопрос данными примера ответа? И, если также возможно, дублировать этот код в работающий codesandbox с некоторым образцом тестового состояния? Кроме того, согласно вашему фрагменту, это было бы item.hours.split(... versus items.hours.split(... , в бит о TypeError есть ‘s’.

4. Извините, я не уверен, что понимаю, вы хотите снимок экрана того, что происходит, когда я запускаю код? извиняюсь за опечатку.

5. Извините за любую путаницу, но не могли бы вы также обновить свой вопрос данными ответа, которые вы получаете из fetch запроса?

Ответ №1:

hours Свойство ваших данных ответа представляет собой массив строк, а не разделенный запятыми список часов в виде строки.

 workers: [
  {
    firstName: "Tom",
    lastName: "Ronson",
    dept: "Sales",
    hireDate: "09/09/2015",
    hours: ["8", "10", "4", "6", "6"]
  },
  {
    firstName: "Bob",
    lastName: "Howser",
    dept: "Acct",
    hireDate: "01/05/2005",
    hours: ["8", "10", "4", "6", "6"]
  },
  {
    firstName: "Jane",
    lastName: "Winger",
    dept: "Legal",
    hireDate: "08/01/2008",
    hours: ["5", "6", "5", "5", "6"]
  }
]
  

Среднее количество отработанных часов может быть вычислено с использованием array::reduce для вычисления суммы часов, деленной на длину массива

 const avg =
    item.hours.reduce((sum, curr) => sum   Number(curr), 0) /
    item.hours.length;
  

Вы можете сопоставить данные как таковые (не забудьте использовать правильный синтаксис JSX, т.Е. <h4>{avg}</h4> versus <h4>avg</h4> )

 {this.state.workers.map((item, index) => {
  const avg =
    item.hours.reduce((sum, curr) => sum   Number(curr), 0) /
    item.hours.length;

  return (
    <li key={index}>
      <h1>
        {item.firstName} {item.lastName}
      </h1>
      <h4>{item.hireDate}</h4>
      <h4>{item.dept}</h4>
      <h4>{avg}</h4> // <-- * use correct JSX syntax
    </li>
  );
})}
  

Редактировать reactjs-вычислять среднее значение из массива строк в объекте json во время рендеринга

Ответ №2:

в каждом объекте JSON есть массив строк. Я хотел бы взять среднее значение этого массива

Из вашего описания item.hours — это массив строк. Но в вашем коде

item.hours.split(",");

Вы обрабатываете его как единственную строку, разделенную запятыми.

Учитывая, что вы получаете TypeError, кажется, что на самом деле это массив строк (желательно, чтобы вы обновили свой вопрос образцами данных).

Чтобы получить среднее значение массива, вы можете использовать reduce :

   const avg = item.hours.reduce((a,b) => a   parseFloat(b),0) / item.hours.length;