[英]Forwarding the checkbox state change to the parent component using callback React Hooks
[英]State management from parent component using hooks
我对 Hooks 很陌生,我正在尝试构建一个小型地址簿。
所以我有两个组成部分:
我希望在单击X时移除卡片。 我设法切换了我的联系人的已删除道具,但我不知道如何强制重新呈现ContactsList
import React, { useState } from 'react' import ContactsList from './components/contacts-list/contacts-list.component' import './App.scss' function App() { const [contacts] = useState([ { key: 0, name: 'Lennon', firstname: 'John', notes: 'smart guy', deleted: false }, { key: 1, name: 'Starr', firstname: 'Ringo', notes: 'funny guy', deleted: false } ]) return ( <div className='App'> <ContactsList contacts={contacts} /> </div> ) } export default App
import React, { useState, useEffect } from 'react' import ContactCard from '../contact-card/contact-card.component' import './contacts-list.styles.scss' function ContactsList(props) { const [contacts, setContacts] = useState(props.contacts) return ( <div className='contacts-list'> <span className='title'>Contacts</span> {contacts .filter(contact => contact.deleted === false) .map(contact => ( <ContactCard name={contact.name} firstname={contact.firstname} notes={contact.notes} deleted={contact.deleted} /> ))} <hr /> </div> ) } export default ContactsList
import React, { useState } from 'react' import './contact-card.styles.scss' function ContactCard(props) { const [contact, setContact] = useState([ { name: props.name, firstname: props.firstname, notes: props.notes, deleted: false } ]) function deleteContact() { const currentContact = [...contact] currentContact[0].deleted = true setContact(currentContact) } return ( <div className='contact-card'> <span className='contact-name'>{props.name}</span> <span className='delete-contact' onClick={deleteContact}> ✕ </span> <br /> <span className='contact-firstname'>{props.firstname}</span> <hr className='separator' /> <span className='contact-notes'>{props.notes}</span> </div> ) } export default ContactCard
这里真的有几个选项,最简单的可能只是传递一个“onContactDeleted”道具并回调给父母,让他们知道更新状态。 这种方法并不总是最干净的,尤其是对于高度嵌套的组件,但我会推荐它作为开始,因为它确实是帮助您了解 prop 和 state 更改如何工作的最普通的方法。 请注意,我保留了您的软删除方法,但您也可以将其从列表中删除。
卡片
import React, { useState } from 'react'
import './contact-card.styles.scss'
function ContactCard(props) {
function deleteContact(key) {
props.onContactDeleted(key)
}
return (
<div className='contact-card'>
<span className='contact-name'>{props.name}</span>
<span className='delete-contact' onClick={() => deleteContact(props.contactKey)}>
✕
</span>
<br />
<span className='contact-firstname'>{props.firstname}</span>
<hr className='separator' />
<span className='contact-notes'>{props.notes}</span>
</div>
)
}
export default ContactCard
列表
import React, { useState, useEffect } from 'react'
import ContactCard from '../contact-card/contact-card.component'
import './contacts-list.styles.scss'
function ContactsList(props) {
const [contacts, setContacts] = useState(props.contacts)
return (
<div className='contacts-list'>
<span className='title'>Contacts</span>
{contacts
.filter(contact => contact.deleted === false)
.map(contact => (
<ContactCard
contactKey={contact.key}
name={contact.name}
firstname={contact.firstname}
notes={contact.notes}
deleted={contact.deleted}
onContactDeleted={props.onContactDeleted}
/>
))}
<hr />
</div>
)
}
export default ContactsList
应用程序
import ContactsList from './components/contacts-list/contacts-list.component'
import './App.scss'
function App() {
const [contacts, setContacts] = useState([
{
key: 0,
name: 'Lennon',
firstname: 'John',
notes: 'smart guy',
deleted: false
},
{
key: 1,
name: 'Starr',
firstname: 'Ringo',
notes: 'funny guy',
deleted: false
}
])
return (
<div className='App'>
<ContactsList contacts={contacts}
onContactDeleted={
(key_to_delete) => {
//note this might not be correct, use it as pseudocode
var copy = [...contacts]
var contact = copy.find(x => x.key == key_to_delete)
if(contact)
{
contact.deleted = true;
setContacts(copy)
}
}
}/>
</div>
)
}
export default App
一旦你有了它,你就可以使用诸如 redux 或useContext
钩子之类的东西来共享状态并“切断中间人”
这是我在网上很快找到的useContext
hook的一个例子,不知道它有多好
从你的App
开始,我建议你将你的联系人对象移动到一个常量,因为在这个级别不需要useState
。
// constants.js
export const contacts = [
{
key: 0,
name: 'Lennon',
firstname: 'John',
notes: 'smart guy'
},
{
key: 1,
name: 'Starr',
firstname: 'Ringo',
notes: 'funny guy'
}
]
};
// App.js
import React from 'react';
import { contacts } from './constants';
import ContactsList from './components/contacts-list/contacts-list.component'
import './App.scss'
function App() {
return (
<div className='App'>
<ContactsList contacts={contacts} />
</div>
)
}
export default App
继续ContactList
组件,因为它是呈现每个联系人的组件,我将在此处构建我的状态。 因此,我会知道是否需要事先提供联系人。
import React, { useState } from 'react'
import ContactCard from '../contact-card/contact-card.component'
import './contacts-list.styles.scss'
function ContactsList(props) {
const [contacts, setContacts] = useState(props.contacts);
const handleDeletion = id => {
setContacts(contacts.filter(contact => contact.id !== id));
}
return (
<div className='contacts-list'>
<span className='title'>Contacts</span>
{contacts.length ?
contacts.map(contact =>
<ContactCard
id={contact.id}
name={contact.name}
firstname={contact.firstname}
notes={contact.notes}
handleDeletion={handleDeletion}
/>
) : null}
<hr />
</div>
)
}
export default ContactsList
请注意,我正在将处理删除的函数传递给我的 ContactCard,而我仍然在这里决定是否应该显示我的联系人。
import React from 'react'
import './contact-card.styles.scss'
function ContactCard(props) {
return (
<div className='contact-card'>
<span className='contact-name'>{props.name}</span>
<span className='delete-contact' onClick={() => props.handleDeletion(props.id)}>
✕
</span>
<br />
<span className='contact-firstname'>{props.firstname}</span>
<hr className='separator' />
<span className='contact-notes'>{props.notes}</span>
</div>
)
}
export default ContactCard
我没有试过代码,但我认为你应该走这条路。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.