用删除功能反应js问题

时间:2018-10-13 19:19:25

标签: javascript reactjs crud

所以我一直在尝试找出我要做出反应的联系人应用程序的删除功能。到目前为止,我有一个部分起作用的removeContact函数。它将删除一个联系人,但不会删除正确的联系人,而是始终删除第一个联系人。在过去的两周中,我一直在这个问题上停留,从我看到的结果来看,我认为我没有获得该函数来正确接收我的联系人对象的ID。这让我发疯,所以任何帮助都将不胜感激。谢谢! 以下是我的三个组成部分;应用,联系人列表和contactCard。

import React, { Component } from 'react';
import NavBar from './components/Menu/NavBar';
import SideBar from './components/Menu/SideBar';
import AddForm from './components/Menu/AddForm';
import ContactList from './components/Contacts/ContactList';






class App extends Component {
  constructor(props){
    super(props);
    this.state = {

      contacts: [
        {first:'Josh',last:'McDaniel',number:'555-666-7777',email:'joshmcdaniel@gmail.com',area:'Mount Morris, Ny',instagram:'https://www.instagram.com/mcdanije/', facebook:'https://www.facebook.com/josh.mcdaniel.5201', linkedin:'https://www.linkedin.com/in/mcdanije/',twitter:'https://twitter.com/'},
        {first:'Briana',last:'McDaniel',number:'888-999-1111',email:'brianamcdaniel@gmail.com',area:'Mount Morris, Ny',instagram:'https://www.instagram.com/mcdanije/', facebook:'https://www.facebook.com/josh.mcdaniel.5201', linkedin:'https://www.linkedin.com/in/mcdanije/',twitter:'https://twitter.com/'},
        {first:'Finn',last:'McDaniel',number:'222-333-4444',email:'finnmcdaniel@gmail.com',area:'Mount Morris, Ny',instagram:'https://www.instagram.com/mcdanije/', facebook:'https://www.facebook.com/josh.mcdaniel.5201', linkedin:'https://www.linkedin.com/in/mcdanije/',twitter:'https://twitter.com/'},
        {first:'Josh',last:'McDaniel',number:'555-666-7777',email:'joshmcdaniel@gmail.com',area:'Mount Morris, Ny',instagram:'https://www.instagram.com/mcdanije/', facebook:'https://www.facebook.com/josh.mcdaniel.5201', linkedin:'https://www.linkedin.com/in/mcdanije/',twitter:'https://twitter.com/'},
        {first:'Briana',last:'McDaniel',number:'888-999-1111',email:'brianamcdaniel@gmail.com',area:'Mount Morris, Ny',instagram:'https://www.instagram.com/mcdanije/', facebook:'https://www.facebook.com/josh.mcdaniel.5201', linkedin:'https://www.linkedin.com/in/mcdanije/',twitter:'https://twitter.com/'},
        {first:'Finn',last:'McDaniel',number:'222-333-4444',email:'finnmcdaniel@gmail.com',area:'Mount Morris, Ny',instagram:'https://www.instagram.com/mcdanije/', facebook:'https://www.facebook.com/josh.mcdaniel.5201', linkedin:'https://www.linkedin.com/in/mcdanije/',twitter:'https://twitter.com/'},
      ],
        toggle:true,
        class: 'modalClose', 
        searchField:'',

        first: '',
        last: '',
        number: '',
        email:'',
        area:'',
        instagram: '',
        facebook: '',
        linkedin:'',
        twitter:''
            }
    }



  //functions for modal start//
addModalToggle = () => {
   this.setState({class:'modal'})
}
closeModalToggle = () =>{
  this.setState({class:'modalClose'})
}
  //functions for modal start//

  //functions that capture form data start//
firstChange = (event) => {
  this.setState({first:event.target.value})
  console.log(this.state.first)
}
lastChange = (event) => {
  this.setState({last:event.target.value})
  console.log(this.state.last)
}
numberChange = (event) => {
  this.setState({number:event.target.value})
  console.log(this.state.number)
}
emailChange = (event) => {
  this.setState({email:event.target.value})
  console.log(this.state.email)
}
locationChange = (event) => {
  this.setState({area:event.target.value})
  console.log(this.state.area)
}
instagramChange = (event) => {
  this.setState({instagram:event.target.value})
}
  //functions that capture form data end//

  //logic for adding contact object to state start//
submitData = (event) => {
    if (this.state.first==''||this.state.last==''||this.state.number==''||this.state.email==''||this.state.area==''){
      alert('Please Fill In All Fields')
      event.preventDefault();
    }else {
 let newContact = {
    first:this.state.first,
    last:this.state.last,
    number:this.state.number,
    email:this.state.email,
    area:this.state.area,
    instagram:this.state.instagram,
    facebook:this.state.facebook,
    linkedin:this.state.linkedin,
    twitter:this.state.twitter
  }


this.setState({contacts:this.state.contacts.concat([newContact])})
  document.getElementById("form").reset();
this.setState({class:'modalClose'})
this.setState({
  first:'',
  last:'',
  number:'',
  email:'',
  area:'',
  instagram:'',
  facebook:'',
  linkedin:'',
  twitter:''
})
event.preventDefault();
    }
}
  //logic for adding contact object to state end//

  searchFieldChange = (event) => {
    this.setState({searchField:event.target.value})
  }

  /*removeContacts = (event) => {
    let array = this.state.contacts; 
    let index = array.indexOf(event.target.value)
    array.splice(index,1);
    this.setState({contacts: array});
  }*/

  /*removeContacts = (id) =>{
    this.setState({
      contacts:this.state.contacts.filter((contacts,id)=> contacts.id != id)
    })
  }  */
  removeContacts = (key) => {
    const contacts = this.state.contacts; 
    contacts.splice(key,1);
    this.setState({contacts: contacts});
  }



  render() {
    const {contacts, searchField} = this.state;
    const filteredContacts =contacts.filter(contacts =>{
      return contacts.first/* this is for side bar letters [0]*/.toLowerCase().includes(searchField.toLowerCase());
    })
    return (
      <div className='container'>
        <NavBar         
        modalToggle={this.addModalToggle} 
        search={this.searchFieldChange}
        />
        <AddForm  
        clear={this.clearBtn}
        closeModal={this.closeModalToggle}
        showAdd={this.state.class} 
        submitData={this.submitData} 
        firstChange={this.firstChange} 
        lastChange={this.lastChange} 
        numberChange={this.numberChange}
        emailChange = {this.emailChange}
        locationChange = {this.locationChange}
        instagramChange = {this.instagramChange}
        facebookChange = {this.facebookChange}
        linkedinChange = {this.linkedinChange}
        twitterChange = {this.twitterChange}
        />
        <ContactList 
        contacts={filteredContacts} 
        removeContacts={this.removeContacts}
        />
      </div>
    );
  }
}

export default App;



import React from 'react';
import ContactCard from './ContactCard';

const ContactList = ({contacts,removeContacts}) =>{


    return (
        <div className = 'contactDisplay' >

        {contacts.map((contact,i) =>{
            return (
                <ContactCard 
                /*key={i} 
                id={i}
                first={contacts[i].first} 
                last={contacts[i].last} 
                email={contacts[i].email} 
                number={contacts[i].number} 
                area={contacts[i].area} 
                instagram={contacts[i].instagram}
                facebook={contacts[i].facebook}
                linkedin={contacts[i].linkedin}
                twitter={contacts[i].twitter}*/
                contacts={contacts[i]}
                removeContacts={removeContacts}
                />
            );
        })
        }
        </div>
    );
}

export default ContactList;

import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faInstagram } from '@fortawesome/free-brands-svg-icons';
import { faFacebookF } from '@fortawesome/free-brands-svg-icons';
import { faLinkedinIn } from '@fortawesome/free-brands-svg-icons';
import { faTwitter } from '@fortawesome/free-brands-svg-icons';
import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import { faTrashAlt } from '@fortawesome/free-solid-svg-icons';


const ContactCard = ({removeContacts,contacts}) =>{
    const {first,last,number,email,area,instagram,facebook,linkedin,twitter} = contacts;

    return (
        <div className='contactCard'>
            <div className='cardTop'>
               <img className='contactPhoto' src= 'https://via.placeholder.com/130x130' alt='person'/> 
                <h2>{first} {last} <button className='editBtn'><FontAwesomeIcon icon={faPencilAlt} /> </button><button className='editBtn' onClick={ removeContacts }><FontAwesomeIcon icon={faTrashAlt} /></button></h2> 
                <hr/>
            </div>
                <div className= 'cardBottom'>
                    <p>Phone Number: {number} </p>
                    <p>Email Address: {email}</p>
                    <p>Location: {area}</p>
                </div>
                <footer className='cardFooter'> 
                    <button type='button' className='instagram'><a href= {instagram} target="_blank">
                    <FontAwesomeIcon icon={faInstagram} />
                    </a></button>
                    <button type='button' className='facebook'><a href= {facebook} target="_blank">
                    <FontAwesomeIcon icon={faFacebookF} />
                    </a></button>
                    <button type='button' className='linkedin'><a href= {linkedin} target="_blank">
                    <FontAwesomeIcon icon={faLinkedinIn} />
                    </a></button>
                    <button type='button' className='twitter'><a href= {twitter} target="_blank">
                    <FontAwesomeIcon icon={faTwitter} />
                    </a></button>
                </footer>
            </div>

    );
}

export default ContactCard;

2 个答案:

答案 0 :(得分:0)

问题在于您永远不会将密钥传递给函数。
发生了以下情况:

t = [1, 2, 3]
t.splice(undefined, 1)
// now, t = [2, 3]

未定义将转换为0。因此,您始终删除第一个元素。

此外,您正在过滤App中的联系人列表,然后再将其传递给调用remove方法的ContactList。因此ContactList中可用的键与状态列表中的索引不匹配。考虑使用instagram应该是唯一的。
然后,代码更新为:

const ContactList = ({contacts,removeContacts}) =>{
    return (
        <div className = 'contactDisplay' >
        {contacts.map((contact,i) =>{
            return (
                <ContactCard 
                ...
                contacts={contacts[i]}
                removeContacts={() => removeContacts(contact.instagram)}
                />
            );
        })
        }
        </div>
    );
}

removeContacts = (insta) => {
  const contacts = this.state.contacts; 
  const idx = contacts.findIndex(c => c.instagram === insta);
  if (idx >= 0) {
    contacts.splice(idx ,1);
    this.setState({contacts: contacts});
  }
}

欢呼

答案 1 :(得分:0)

永远不要使用键来标识数组中的对象,它们只能作为React在JSX列表中的对象的唯一标识符而专用。您需要使用数组中的唯一标识符来找到要删除的项目,因此您应该在数组中引入id属性,或使用现有的唯一键(例如电子邮件)。考虑以下设置:

removeContacts = (email) => {
    const { contacts } = this.state;
    const newContacts = contacts.filter(item => item.email !== email);
    this.setState({ contacts: newContacts });
}

const ContactList = ({contacts,removeContacts}) =>{
    return (
        <div className = 'contactDisplay' >

        {contacts.map((contact,i) =>{
            return (
                <ContactCard 
                /*key={i} 
                id={i}
                first={contacts[i].first} 
                last={contacts[i].last} 
                email={contacts[i].email} 
                number={contacts[i].number} 
                area={contacts[i].area} 
                instagram={contacts[i].instagram}
                facebook={contacts[i].facebook}
                linkedin={contacts[i].linkedin}
                twitter={contacts[i].twitter}*/
                contacts={contacts[i]}
                removeContacts={() => removeContacts(contact.email)}
                />
            );
        })
        }
        </div>
    );
}