React Table w / JSON API-хуков? - PullRequest
       41

React Table w / JSON API-хуков?

0 голосов
/ 22 апреля 2020

Итак, я начал учиться использовать React Table (https://github.com/tannerlinsley/react-table), это довольно изящно. Тем не менее, я являюсь промежуточным специалистом в React (я понимаю основы c lifecycle / props / et c ..), но хуки для меня довольно новые.

Я решил использовать его в личном проекте, который был в основном занятия. Он вызывает API (который я написал в Rails) для возврата некоторой базовой информации c JSON. Я использую ax ios (https://github.com/axios/axios) для вызова API.

Из изучения ловушек реагирования я преобразовал то, что изначально было моим вызовом componentDidMount(), в вызов useEffect(). Ниже приведен код для таблицы и контейнера таблицы (для приложения, которое работает с датчиками, отсюда и названия)

Контейнер датчика:

import React, { useState, useEffect } from "react";
import axios from "axios";
import SensorCard from "./SensorCard";
import SensorTable from "./SensorTable";
import "../Styles/Components/_SensorContainer.css";

function SensorContainer() {
  const [sensors, setSensors] = useState([]);
  const [data, setData] = useState([])

  useEffect(() => {
    // GET sensor list from API
    axios
    .get("http://localhost:3000/api/v1/devices.json")
    .then((response) => {
      // handle success
      console.log(response);
      setSensors(response.data.data)
    })
    .then(() => {
      console.log(sensors)
      console.log(sensors[0].attributes)
      console.log(name)
      console.log(serialNumber)
      console.log(deviceStatus)
      const { name, 'serial-number':serialNumber, 'device-status':deviceStatus} = sensors[0].attributes
      const data = sensors.map(sensor => 
        ({ 
          id: sensor.id, 
          name: name, 
          serialNum: serialNumber,
          status: deviceStatus
        })
      )
    setData(data)
    })
    .catch((error) => {
      console.log(error);
    })
  }, [sensors.length]);





  // const data = React.useMemo(
  //   () => [
  //     {
  //       id: '1',
  //       name: 'TEMP001',
  //       serialNum: 'Temp Sensor',
  //       status: 'Active',
  //     },
  //     {
  //       id: '2',
  //       name: 'TEMP002',
  //       serialNum: 'Temp Sensor',
  //       status: 'Unknown',
  //     },
  //     {
  //       id: '3',
  //       name: 'HUM001',
  //       serialNum: 'Humidity Sensor',
  //       status: 'Active',
  //     },
  //   ],
  //   []
  // )

  const columns = React.useMemo(
    () => [
      {
        Header: 'ID',
        accessor: 'id', // accessor is the "key" in the data
      },
      {
        Header: 'Name',
        accessor: 'name',
      },
      {
        Header: 'Serial Number',
        accessor: 'serialNum',
      },
      {
        Header: 'Status',
        accessor: 'status',
      },
    ],
    []
  )
  return (
    <div>
      <SensorTable columns={columns} data={data} />
    </div>
  )
}

export default SensorContainer;

Таблица датчиков:

import React from "react";
import {
  useTable,
  useGroupBy,
  useFilters,
  useSortBy,
  useExpanded,
  usePagination,
} from "react-table";
import "../Styles/Components/_SensorTable.css";

function SensorTable({ columns, data }) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
  } = useTable({ columns, data })

  // Render the UI for your table
  return (
    <table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
      <thead>
        {headerGroups.map(headerGroup => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map(column => (
              <th
                {...column.getHeaderProps()}
                style={{
                  borderBottom: 'solid 3px red',
                  background: 'aliceblue',
                  color: 'black',
                  fontWeight: 'bold',
                }}
              >
                {column.render('Header')}
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {rows.map(row => {
          prepareRow(row)
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map(cell => {
                return (
                  <td
                    {...cell.getCellProps()}
                    style={{
                      padding: '10px',
                      border: 'solid 1px gray',
                      background: 'papayawhip',
                    }}
                  >
                    {cell.render('Cell')}
                  </td>
                )
              })}
            </tr>
          )
        })}
      </tbody>
    </table>
  )
}

export default SensorTable;

Итак, я сталкиваюсь с несколькими "проблемами проектирования", касающимися этого:

  1. Как / Где люди обычно устанавливают / хранят данные столбца и данные «data» при использовании таблицы реакции. Я бы взял const для столбцов .... но где хранятся данные? (Обычно я храню его в состоянии в классе, но так как я пытаюсь использовать хуки, я не уверен)
  2. Я чувствую, что мой useEffect() не подходит для получения данных API. Я также столкнулся с ошибкой, когда она постоянно работала. Я видел, как кто-то предложил проверить длину, чтобы предотвратить это ... но это кажется хакерским. Какой правильный способ сделать это?
  3. Я не могу понять, как сопоставить данные, как я хочу с React.useMemo Я тоже не могу найти никаких примеров (Таблица реакции реагирования требует этого). Любой совет?

Я просто действительно не уверен, как правильно настроить это. Кажется, я не могу найти примеры людей, использующих таблицу реакции С json api fetching.

1 Ответ

1 голос
/ 27 апреля 2020

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

  1. Как / Где люди обычно устанавливают / хранят данные столбца и данные «данных» при использовании таблицы реагирования. Я бы взял const для столбцов .... но где хранятся данные? (Обычно я храню его в состоянии в классе, но поскольку я пытаюсь использовать хуки, я не уверен)

    Ответ

    • Он основан на требование к заявке.
    • Если данные необходимо сохранить на стороне клиента и совместно использовать между несколькими модулями / компонентами, используйте redux для хранения ваших данных.
    • Если данные требуются (не хранятся в течение длительного времени) только при посещении пользователем экрана, сохраните данные в состоянии компонента .
  2. Мне кажется, что мой useEffect() не подходит для получения данных API. Я также столкнулся с ошибкой, когда она постоянно работала. Я видел, как кто-то предложил проверить длину, чтобы предотвратить это ... но это кажется хакерским. Как правильно это сделать?

    Ответ :

    • Согласно вашему коду, нет необходимости / необходимости передавать зависимости в useEffect крючок. (Это происходит потому, что вы пытаетесь поддерживать одни и те же данные в двухкомпонентном состоянии, например, data и датчиков . Но в этом нет необходимости - PS см. Прилагаемый код в приведенной выше ссылке. Посмотрите на Условная фильтрация эффекта
    • Если вы хотите запустить эффект при монтировании только один раз (componentDidMount), вы можете передать пустой массив ([]) в качестве второго аргумента Так что он никогда не перезапускается.
  3. Я не могу понять, как сопоставить данные, как я хочу с React.useMemo Я не могу найти никаких примеров либо (очевидно, таблица реагирования требует этого). Любой совет?

    Ответ :

    • Что вы подразумеваете под как сопоставить данные? . Хотите выполнить какое-то преобразование объекта ответа из API? Если да, вы можете использовать любые встроенные методы Javascript или стороннюю библиотеку, например ramda или loda sh
    • useMemo не требуется в вашем случае, так как вы не делаете никаких сложных операция, и ваш источник данных - API.
    • Некоторые примечания, упомянутые в reactjs документации относительно useMemo hook

Помните, что функция прошла использовать Memo работает во время рендеринга. Не делайте там ничего, что вы обычно не делаете во время рендеринга. Например, побочные эффекты принадлежат useEffect, а не useMemo.

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

См. Строки, отмеченные <---- в приведенном ниже коде

  // const [sensors, setSensors] = useState([]); No need to maintain same data in two state variables
  const [data, setData] = useState([])

  useEffect(() => {
    // GET sensor list from API
    axios
    .get("http://localhost:3000/api/v1/devices.json")
    // .then((response) => {  
    //  handle success
    //  console.log(response);
    //  setSensors(response.data.data)
    // }) <------- this is not required
    .then((response) => {
      // ......
      const data = response.data.data.map(sensor => 
        ({ 
          id: sensor.id, 
          name: sensor.name, 
          serialNum: sensor.serialNumber,
          status: sensor.deviceStatus
        })
      )
      setData(data)
    })
    .catch((error) => {
      console.log(error);
    })
//  }, [sensors.length]);
}, []); // <--------- like componentDidMount in classBased components 

Добавлен окончательный код в рабочие коды и поле здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...