Сетка реагирующих данных не рендерится при добавлении строк новостей - PullRequest
0 голосов
/ 11 апреля 2019

Я новичок в React и работаю над приложением MERN Stack. Я включил react-data-grids в свое приложение. Я использую axios для извлечения данных строк. Я создал систему разбиения на страницы, поэтому, когда пользователь прокручивает до конца таблицы данных, код выбирает новые строки и добавляет их в состояние компонента. Компонент ReactDataGrid использует строки из состояния.

Теперь мой вопрос заключается в том, почему ReactDataGrid не выполняет повторный рендеринг, несмотря на добавление строк в состояние.

Родительский компонент (Table.jsx)

import React from 'react'
import RDGView from 'components/RDGView/RDGView.jsx'
import {
  Card,
  CardHeader,
  CardBody,
  CardFooter,
  CardTitle,
  Row,
  Col,
  Alert
} from 'reactstrap'
import Stats from 'components/Stats/Stats.jsx'
import { PulseLoader } from 'react-spinners'
import { css } from '@emotion/core'
import API from 'config/API'

import 'views/Table/Table.scss'

const override = css`
  display: block;
  margin: 0 auto;
  border-color: red;
  padding: 1rem;
  text-align: center;
`
class Table extends React.Component {
  state = {
    loading: true,
    error: '',
    table: {},
    rows: [],
    tableFound: false,
    page: 0,
    count: null
  }
  loadNextPage = () => {
    if (
      this.state.count === null ||
      this.state.rows.length < this.state.count
    ) {
      API.get(`/tables/${this.props.match.params.id}?page=${this.state.page}`)
        .then(res => res.data)
        .then(data => {
          // Format data
          this.setState({
            loading: false,
            table: data.data.table,
            tableFound: true,
            page: this.state.page + 1,
            count: data.data.count
          })
          this.setState(state => {
            let rows = state.rows
            rows = rows.concat(data.data.rows)
            console.log(rows)
            return { rows }
          })
        })
        .catch(err => {
          let error = 'Unknown Error'
          if (typeof err.response !== 'undefined') {
            if (typeof err.response.data.message !== 'undefined') {
              error = err.response.data.message
            }
          }
          this.setState({
            error,
            loading: false
          })
        })
    }
  }
  createTable = () => {
    console.log('Cilcked!')
  }
  componentWillMount() {
    // Get all the Table
    this.loadNextPage()
  }
  onGridRowsUpdated = (fromRow, toRow, updated) => {
    // Update rows at the DB side
    API.put(`tables/${this.state.table._id}`, {
      row: this.state.rows[fromRow]._id,
      updated
    })
      .then(res => res.data)
      .then(data => {})
      .catch(err => {
        let error = ''
        if (typeof err.response.data.message !== 'undefined') {
          error = err.response.data.message
        } else {
          error = 'Unknown error updating table'
        }
        this.setState({
          error
        })
      })
    this.setState(state => {
      const rows = state.rows.slice()
      rows[fromRow].values = { ...rows[fromRow].values, ...updated }
      return { rows }
    })
  }
  addRow() {
    // Add a new Row
    let newRow = {
      values: {}
    }
    let columns = this.state.table.columns
    let lastRow = this.state.rows[this.state.rows.length - 1]
    columns.map(column => {
      newRow.values[column.key] = column.editable
        ? ' '
        : lastRow.values[column.key]
    })
    newRow.values.id = lastRow.values.id + 1
    API.post(`/rows/${this.state.table._id}`, { row: newRow })
      .then(res => res.data)
      .then(data => {
        this.setState(state => {
          let rows = state.rows
          rows.push(newRow)
          return { rows }
        })
      })
      .catch(err => {
        let error = 'Unknown Error'
        if (typeof err.response !== 'undefined') {
          if (typeof err.response.data.message !== 'undefined') {
            error = err.response.data.message
          }
        }
        this.setState({
          error,
          loading: false
        })
      })
  }
  deleteTable(table) {
    if (window.confirm(`Are you sure to delete ${table.name}`)) {
      API.delete(`/tables/${table._id}`)
        .then(res => res.data)
        .then(data => {
          window.location = '../tables'
        })
        .catch(err => {
          this.setState({
            error: err.response
              ? err.response.data.message || 'Unknown Error'
              : 'Unknown Error'
          })
        })
    }
  }
  render() {
    return (
      <div className="content">
        {this.state.loading ? (
          <PulseLoader
            css={override}
            sizeUnit={'rem'}
            size={1.6}
            color={'#000'}
            loading={this.state.loading}
          />
        ) : (
          <React.Fragment>
            {this.state.error ? (
              <Alert color="danger">{this.state.error}</Alert>
            ) : (
              ''
            )}
            <Row>
              {this.state.tableFound && this.state.rows.length ? (
                <React.Fragment>
                  <RDGView
                    rows={this.state.rows}
                    table={this.state.table}
                    onGridRowsUpdated={this.onGridRowsUpdated}
                    addRow={this.addRow.bind(this)}
                    deleteTable={this.deleteTable.bind(this)}
                    loadNextPage={this.loadNextPage.bind(this)}
                  />
                </React.Fragment>
              ) : (
                <Alert color="danger">Table not found</Alert>
              )}
            </Row>
          </React.Fragment>
        )}
      </div>
    )
  }
}

export default Table

Дочерний компонент: (RDGView.jsx)

import React from 'react'
import { findDOMNode } from 'react-dom'
import PropTypes from 'prop-types'
import ReactDataGrid from 'react-data-grid'
class RDGView extends React.Component {
  constructor(props) {
    super(props)
    this.canvas = null
    this.scrollListener = () => {
      if (
        this.canvas.scrollHeight -
          (this.canvas.scrollTop + this.canvas.clientHeight) <
        10
      ) {
        this.props.loadNextPage()
      }
    }
  }
  state = {
    rows: this.props.rows,
    columns: this.props.table.columns
  }
  onGridRowsUpdated = ({ fromRow, toRow, updated }) => {
    this.props.onGridRowsUpdated(fromRow, toRow, updated)
  }
  componentDidMount() {
    this.canvas = findDOMNode(this).querySelector('.react-grid-Canvas')
    this.canvas.addEventListener('scroll', this.scrollListener)
  }

  componentWillUnmount() {
    if (this.canvas) {
      this.canvas.removeEventListener('scroll', this.scrollListener)
    }
  }
  componentDidUpdate(props, newProps) {
    if (this.state.rows !== newProps.rows) {
      this.setState({
        columns: props.table.columns,
        rows: props.rows
      })
    }
  }
  render() {
    return (
      <React.Fragment>
        <ReactDataGrid
          columns={this.state.columns}
          rowGetter={i => {
            if (i < 0) {
              i = 0
            }
            return this.state.rows[i].values
          }}
          rowsCount={this.state.rows.length}
          minHeight={`20vh`}
          onGridRowsUpdated={this.onGridRowsUpdated.bind(this)}
        />
        <div className="container">
          <div className="jumbotron bg-transparent text-center">
            <div className="btn-group">
              <button
                className="btn btn-danger"
                onClick={() => this.props.deleteTable(this.props.table)}
              >
                Delete Table
              </button>
              <button className="btn btn-warning">Reset Table</button>
            </div>
          </div>
        </div>
      </React.Fragment>
    )
  }
}

RDGView.propTypes = {
  rows: PropTypes.array,
  table: PropTypes.object,
  onGridRowsUpdated: PropTypes.func,
  addRow: PropTypes.func,
  deleteTable: PropTypes.func,
  loadNextPage: PropTypes.func
}

export default RDGView

Может кто-нибудь помочь с этим? Как я могу заставить его перерисоваться, когда строки обновляются. Спасибо!

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