javascript - 如何解决 react 类型错误: Cannot read properties of undefined (reading 'name' )

标签 javascript reactjs

这里我试图进行一个增删改查操作。一切正常,直到我尝试通过他们的 id 更新某些内容时,它才向我显示此错误。对于我所附屏幕截图中的第一个,我能够更新数据,但是当我尝试更新另一个时,它在 selectVendor 函数中向我显示此错误。

#这是我的代码

   import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import axios from 'axios'
import { Link } from 'react-router-dom'
import { Form, Button, Table } from 'react-bootstrap'
import Loader from '../components/Loader'
import Message from '../components/Message'
import Paginate from '../components/Paginate'

function VendorScreen() {
    const [vendors, setVendor] = useState([])
    const [name, setName] = useState("");
    const [userName, setUserName] = useState("");
    const [address, setAddress] = useState("");
    const [profile_picture, setPicture] = useState("");
    const [vendorId,setVendorId]=useState(null)
    const [uploading, setUploading] = useState(false)
    

    const userLogin = useSelector(state => state.userLogin)
    const { userInfo } = userLogin
  
    useEffect(() => {
      getVendors();
    }, [])
    function getVendors() {
      fetch("http://localhost:8000/api/orders/vendors/",{
      method: 'GET',
        headers:{
          'Accept':'application/json',
          'Content-Type':'application/json',
          "Authorization" : `Bearer ${userInfo.token}`,
        },}).then((result) => {
          
          
        result.json().then((resp) => {
          console.warn(resp)
          setVendor(resp)
          setName(resp[0].name)
          setAddress(resp[0].address)
          setVendorId(resp[0].id)
          setPicture(resp[0].profile_picture)
          setUserName(resp[0].user.name)
        })
      })
    }
  
    function deleteVendor(id) {
      fetch(`http://localhost:8000/api/orders/delete/${id}`, {
        method: 'DELETE',
        headers:{
            'Accept':'application/json',
            'Content-Type':'application/json',
            "Authorization" : `Bearer ${userInfo.token}`,
        }
      }).then((result) => {
        result.json().then((resp) => {
          console.warn(resp)
          getVendors()
        })
      })
    }

    
    function selectVendor(id) {
      const item = vendors.find(vendor => vendor.id === id);
    
      console.log(item);
    
      if (item) {
        setName(item.name);
        setAddress(item.address);
        setPicture(item.profile_picture);
        setUserName(item.user?.name); // <-- guard if user is undefined/null
        setVendorId(item.id);

      }
    }


    function updateVendor()
    {
      const formData = new FormData();

          formData.append('File', profile_picture);

      let item={name,address, profile_picture}

      console.warn("item",item)
      fetch(`http://localhost:8000/api/orders/update/${vendorId}`, {
        method: 'PUT',
        headers:{
          'Accept':'application/json',
          'Content-Type':'application/json',
          "Authorization" : `Bearer ${userInfo.token}`,
        },
        body:JSON.stringify(item)
      }).then((result) => {
        result.json().then((resp) => {
          console.warn(resp)
          getVendors()
        })
      })
    }


    const uploadFileHandler = async (e) => {
      const file = e.target.files[0]
      const formData = new FormData()

      formData.append('profile_picture', file)
      formData.append('vendor_id', vendorId)

      setUploading(true)

      try {
          const config = {
              headers: {
                  'Content-Type': 'multipart/form-data',
                  "Authorization" : `Bearer ${userInfo.token}`,
              }
          }

          const { data } = await axios.post('/api/products/upload/vendor/', formData, config)


          setPicture(data)
          setUploading(false)

      } catch (error) {
          setUploading(false)
      }
  }

    return (
      <div className="App">
        <h1>Update User Data With API </h1>
        <Table striped bordered hover responsive className='table-sm'>
          <tbody>
            <tr>
              <td>ID</td>
              <td>Name</td>
              <td>Address</td>
              <td>User</td>
              <td>Picture</td>
              <th></th>
              
            </tr>
            {
              vendors.map((item, i) =>
                <tr key={i}>
                  <td>{item.id}</td>
                  <td>{item.name}</td>
                  
                  <td>{item.address}</td>
                  <td>{item.user.name}</td>
                  <td>{item.profile_picture}</td>
                  <td><button variant='danger' className='btn-sm' onClick={() => deleteVendor(item.id)}><i className='fas fa-trash'></i></button>
                  <button variant='info' className='btn-sm' onClick={() => selectVendor(item.id)}><i className='fas fa-edit'></i></button></td>
  
                </tr>
              )
            }
          </tbody>
          </Table>
          <Paginate pages={pages} page={page} isAdmin={true} />
        <div>

            <br ></br>
            <br ></br>
            <br ></br>
            <br ></br>
        <input type="text" value={name} onChange={(e)=>{setName(e.target.value)}} /> <br /><br />
          <input type="text" value={address} onChange={(e)=>{setAddress(e.target.value)}}  /> <br /><br />
          <Form.Control
                                    type='file'
                                    id='image-file'
                                    label='Choose File'
                                    custom
                                    onChange={uploadFileHandler}
                                >

                                </Form.Control>
                                {uploading && <Loader />}
        
           <button onClick={updateVendor} >Update User</button>  
        </div>
      </div>
    );
  }

export default VendorScreen

我需要为 getbyId 调用 api 吗?我遵循了一个教程,他们能够做到这一点,但我不知道如何做到

这是我的截图

enter image description here

最佳答案

虽然 vendors 是一个数组,但我认为 id 属性实际上不太可能是数组索引。至少,你似乎不应该始终相信它是真实的。

function selectVendor(id) {
  let item=vendors[id-1]; // <-- item likely undefined

  console.log(item.name)
  setName(item?.name)
  setAddress(item?.address)
  setUserName(item?.user.name);
  setVendorId(item?.id);
}

您可能希望通过 idvendors 数组中搜索匹配的 vendor 对象。如果通过谓词函数未找到任何元素,Array.prototype.find 将返回 undefined,因此代码应适当处理这种情况。

示例:

function selectVendor(id) {
  const item = vendors.find(vendor => vendor.id === id);

  console.log(item);

  if (item) {
    setName(item.name);
    setAddress(item.address);
    setUserName(item.user?.name); // <-- guard if user is undefined/null
    setVendorId(item.id);
  }
}

关于javascript - 如何解决 react 类型错误: Cannot read properties of undefined (reading 'name' ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71159322/

相关文章:

javascript - react : is this a good way to implement a shared state subscription?

javascript - 为什么在 Javascript 中使用正则表达式来验证经纬度?

javascript - 类型错误 : Cannot read property 'characters' of undefined

javascript - 为什么默认的 create-react-app 应用程序会立即删除/冗余服务人员?

javascript - 我可以在 React 函数组件中使用 "let"吗?

javascript - SVG 箭头跟随线方向

javascript - 为动态加载的 javascript 文件实现 'error' 回调

javascript - 使用js加密框架还是浏览器的Web Crypto API?

javascript - 是否可以在 CSS 宽度转换上强制硬件加速

javascript - 在 reactjs 中首次运行时在控制台上获取空对象