从表中删除行(无法读取null的属性'data')

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从表中删除行(无法读取null的属性'data')相关的知识,希望对你有一定的参考价值。

我是Gatsbyjs和reactjs的新手,我仍然不太了解props.and状态是如何工作的。

我正在构建这个简单的应用程序,它从API和每个客户的任务列表中获取客户列表。

我正在使用Reach / Router来渲染组件。一切都按预期工作,以显示带有客户列表的表格,当我点击客户时,会显示一个新页面,显示该客户的任务列表。

现在,我正在尝试使表格可编辑。我首先尝试简单地删除一些行。这是我被困的地方。

edit

我相信我得到了Uncaught TypeError: Cannot read property 'data' of null的错误,因为我正在尝试访问由fetch.js类管理的数据(状态)。如何将数据(状态)传递给ClientTasks类?

---

我有以下代码

index.js

import React from "react"
import  createHistory, LocationProvider  from '@reach/router'
import createHashSource from '../utils/hash-source'
import  ToastContainer  from 'react-toastify';

import "../css/main.css"
import "../css/materialize.css"
import "../css/blackjack.css"
import '../../node_modules/react-toastify/dist/ReactToastify.css';


import  NavBar  from '../components/navBar'
import  Main  from '../components/main'

const isClient = typeof window !== 'undefined' && window;

let source 
let history 
if (typeof window !== `undefined` ) 
  source = createHashSource()
  history = createHistory(source)


class App extends React.Component  
  render() 
    return (
      <LocationProvider history=history>
        <div className="app" >
          <NavBar/>
          <Main/>
          <ToastContainer position="bottom-right"/>
        </div>
      </LocationProvider>
    )
  


export default App

main.js

import React from 'react'
import  Router  from "@reach/router"

import  Home  from '../components/home'
import  Customers  from './customers';
import  ClientTasks  from './clientTasks1';


const Main = () => (
  <main className="main container">
      <Router className="row">
        <Home path='/'/>
        <Customers path='customers'/>
        <ClientTasks path="customers/tasks/:customerId"/>
      </Router>
  </main>
)

export  Main 

fetch.js

我使用此文件作为单个类组件工作,帮助我获取我正在显示的表(客户和任务)的数据。它工作正常。可能有更好的方法,但现在这就是我这样做的方式。任何指针都是受欢迎的。

import React,  Component  from 'react'

const axios = require('axios')
class Fetch extends React.Component 
    constructor(props) 
      super(props);

      this.state = 
        data: null,
        isLoading: true,
        error: null,
      ;
    

    componentDidMount() 
      this.setState( isLoading: true );

      axios.get(this.props.url)
        .then(result => this.setState(
          data: result.data,
          isLoading: false
        ))
        .catch(error => this.setState(
          error,
          isLoading: false
        ));
    

    render() 
      return this.props.children(this.state);
    
  


export default Fetch

Customers.js

这是我显示客户表的地方。我有每个客户的链接,并在“到达/路由器”的帮助下渲染cutomer任务表。

import React,  Component  from 'react'
import  Link  from "@reach/router"

import Fetch from './fetch'
import  UploadForm  from './upLoadtoS3'
import  AnimatedDiv  from './AnimatedDiv'

const APIURL = `https://SomeAIPURL`
let APIQuery = `customers`

const Customers = () => (
  <Fetch url=APIURL + APIQuery>
    ( data, isLoading, error ) => 
      if (!data) 
        return (
          <div className="progress">
            <div className="indeterminate"></div>
          </div>)
      
      if (error) 
        return <p>error.message</p>;
      
      if (isLoading) 
        return (
          <div className="progress">
            <div className="indeterminate"></div>
          </div>)
      
      return (
        <AnimatedDiv className='col m12 s12'>
          <h1> Client List </h1>
          <table className='highlight'>
            <thead>
              <tr>
                <th>#</th>
                <th>Client ID</th>
                <th>Status</th>
              </tr>
            </thead>
            <tbody>
              data.map((customer, i) => (
                <tr key=customer.customerid>
                  <td>i + 1</td>
                  <td>
                    <Link to=`tasks/$customer.customerid`>customer.customerid</Link>
                  </td>
                  <td>customer.enabled</td>
                </tr>
              ))
            </tbody>
          </table>
          <UploadForm></UploadForm>
        </AnimatedDiv>
      );
    
    
  </Fetch>
)
export  Customers 

ClientTasks.js

再次调用Fetch并使用从API中提取的数据填充表。我用另一个文件来定义这个表的内容。 listTasks.js

import React,  Component  from 'react'
import  Link  from "@reach/router"

import Fetch from './fetch'
// import Delete from './delete'
import  AnimatedDiv  from './AnimatedDiv'
import DisplayList from './listTasks'

const APIURL = `https://SomeAIPURL`
const CUSTOMERQUERY = `tasks?customerid=`
const TASKQUERY = `&taskid=`



class ClientTasks extends React.Component 

  handleDelete(taskToBeDeleted) 
    // console.log(taskToBeDeleted);
    let newData = this.state.data.filter((_data) => 
      return _data != taskToBeDeleted
    );
    this.setState( data: newData )
    

  render() 
    let customerId = this.props.customerId
    return (
      <Fetch url=APIURL + CUSTOMERQUERY + customerId>
        ( data, isLoading, error ) => 
          if (!data) 
            return (
              <div className="progress">
                <div className="indeterminate"></div>
              </div>)
          
          if (error) 
            return <p>error.message</p>;
          
          if (isLoading) 
            return (
              <div className="progress">
                <div className="indeterminate"></div>
              </div>)
          
          else 
          return (
            <AnimatedDiv className='col m12 s12'>
              <h1>customerId Tasks</h1>
              <table id="customerList" className="highlight" >
                <thead>
                  <tr>
                    <th>Task ID</th>
                    <th>Qty</th>
                    <th>Asset Category</th>
                    <th>Asset</th>
                    <th>Location</th>
                    <th>Status</th>
                    <th>Action</th>
                  </tr>
                </thead>

              <DisplayList handleDelete=this.handleDelete.bind(this) data=data/>

              </table>
              <Link to='/customers'> Back to Client List ... </Link>
            </AnimatedDiv>

          )
          
        
        
      </Fetch>
    )
  


export  ClientTasks 

>

这里我有一个onClick函数在handleDelete文件中运行ClientTasks.js

如果我console.log(taskstobedeleted)然后控制台显示我想要删除的行的内容。这是我得到的。然后我试图在clientasks.js中使用以下功能,但我在控制台中得到一个错误说Cannot read property 'data' of null),我相信这是因为数据的道具是这个clientTasks类可访问。

我还在学习,并且有更好的方法来构建代码,但是我已经碰壁了,我不想从头开始重建应用程序,如果我这样做,我可能会使用redux,但这是后来的另一个教训。我认为我的这个项目足够小,还不需要Redux。

可以以某种方式给我任何指针,如何删除我的表行?

  handleDelete(taskToBeDeleted) 
    // console.log(taskToBeDeleted);
    let newData = this.state.data.filter((_data) => 
      return _data != taskToBeDeleted
    );
    this.setState( data: newData )
    

Listtasks.js

import React from 'react'
import  Icon  from 'react-icons-kit'
import  ic_delete_forever  from 'react-icons-kit/md/ic_delete_forever'

export default class DisplayList extends React.Component 

    render() 
        return (

            <tbody>
                this.props.data.map((task) => (
                    <tr key=task.taskid>
                        <td>task.taskid</td>
                        <td>task.qty</td>
                        <td>task.category</td>
                        <td>task.asset</td>
                        <td>task.location</td>
                        <td>task.enabled</td>
                        <td>
                            <button style= padding: '0px', background: 'transparent', border: '0', cursor: 'pointer'  onClick=this.props.handleDelete.bind(this, task) >
                                <Icon style= color: 'red'  icon=ic_delete_forever />
                            </button>
                        </td>
                    </tr>
                ))
            </tbody>
        )
    


答案

我认为你的功能应该是这样的:

  handleDelete(taskToBeDeleted) 
    // console.log(taskToBeDeleted);
    let newData = this.state.data.filter((_data) => _data.taskid != taskToBeDeleted.taskid);
    this.setState( data: newData )
    

如果您的控制台为您提供了所需的对象,那么首先,您不需要返回箭头函数,因为返回是隐式的。其次,所有的任务都已返回,因为你要求两个对象是相同的,即使它们内部具有相同的键值对,它们也总是假的。他们有不同的参考。这就是为什么我使用id,因为我认为该键的值是数字,你可以用operator ==或!=来评估它

以上是关于从表中删除行(无法读取null的属性'data')的主要内容,如果未能解决你的问题,请参考以下文章

一段时间后从表中删除行

第二十章 更新和删除数据

从表中获取特定用户的所有行以及总和

SQL问题,请教高手

eslint 错误无法读取 null 的属性“范围”

从表中删除不会删除行