我有一个页面,它将列出所有书籍的管理。如果管理员点击任何特定书籍的编辑按钮,我的应用程序将显示一个自定义模式,它将显示输入框中的值,并让管理员编辑它。
我的组件的最小示例:
import styles from '../../styles/EditPopup.module.css'
export default function EditPopup({ show, setPopupVisibility, item_data }){
const onSaveEdit = () => {
//TODO
}
return (
<div className={ styles.popup } style={ show ? {} : { display: 'none' } }>
<input type="text" defaultValue={ item_data.title } />
<input type="text" defaultValue={ item_data.author } />
<textarea defaultValue={ item_data.desc}></textarea>
<button onClick={ () => onSaveEdit() } >SAVE</button>
<button onClick={ () => setPopupVisibility( false ) }>CANCEL</button>
</div>
)
}
我的页面的最小示例它列出了所有带有编辑按钮的图书:
const [selected_book, setSelectedBook] = useState({ id: '', title: '', author: '', desc: '' })
const [show_edit_popup, setShowEditPopup] = useState(false)
return (
<EditPopup
show={ show_edit_popup }
setPopupVisibility={ (visibility) => setShowEditPopup( visibility ) }
item_data={ selected_book }
/>
<div>
{ all_books.map( (item, i) => (
<div key={ item.id }>
Title: {item.title}
Author: {item.author}
Desc: {item.desc}
<a href="#"
onClick={ (e) => {
e.preventDefault()
setSelectedBook( prev => ({ ...prev, id: item.id, title: item.title, author: item.author, desc: item.desc}) )
setShowEditPopup( true )
} }
>EDIT</a>
</div>
))}
</div>
)
问题是,它在弹出框中不能正常工作。在弹出框中,for语句将始终为空。如果我在任何输入中键入一些新值,然后关闭弹出窗口并单击任何其他项上的EDIT按钮,那么我之前在输入中输入的值仍然存在。其次,我对如何获得新的用户输入感到困惑。我应该用useRef
还是useState
来配onChange
我知道这对你们所有人来说都很简单,但我想我想得太多了。
你没有正确处理状态,所以用useState
和onChange
。对于您的输入,将onChange
设置为来自父组件的回调函数,将event.target.value
传递给它,并将它们设置为在父组件中启动的状态。此外,通过将它们批处理在一个状态中来最小化状态声明。代码可以像这样:
import styles from '../../styles/EditPopup.module.css'
export default function EditPopup({ data, handleClosePopUp, onSaveEdit, handleChangeInputs }){
return (
<div className={ styles.popup } style={ data.show ? {} : { display: 'none' } }>
<input type="text" onChange={e => handleChangeInputs(e.target.value, 'title')} value={ data.title } />
<input type="text" onChange={e => handleChangeInputs(e.target.value, 'author')} value={ data.author } />
<textarea onChange={e => handleChangeInputs(e.target.value, 'desc')} value={ data.desc}></textarea>
<button onClick={onSaveEdit} >SAVE</button>
<button onClick={handleClosePopUp}>CANCEL</button>
</div>
)
}
和父母
const initialData = { show: false, id: '', title: '', author: '', desc: '' }
const [popUpData, setPopUpData] = useState({...initialData})
const handleChangeInputs = (text, type) => {
setPopUpData(data => {...data, data[type] = text})
}
const onSaveEdit = () => {
//do your API call or whatever it updates all_books
}
return (
<EditPopup
handleChangeInputs={handleChangeInputs}
onSaveEdit={onSaveEdit}
handleClosePopUp={ () => setPopUpData({...initialData}) }
data={ popUpData }
/>
<div>
{ all_books.map(item) => (
<div key={ item.id }>
Title: {item.title}
Author: {item.author}
Desc: {item.desc}
<a href="#"
onClick={ (e) => {
e.preventDefault()
setPopUpData({ show: true, ...item})
} }
>EDIT</a>
</div>
))}
</div>
)