单击删除按钮时,列出react组件上未使用useReducer()更新的项



我在ReactContext中使用use reducer来处理一些签名显示。在Messages和messagesForm组件上,分派功能运行良好。但在prevMessages内部则不然。我尝试了控制台日志(json(,但它在handleDelete梅斯((函数中也不起作用。为了解决这个问题,我想尽一切办法。

在这里我提供我的代码:

这是父组件-Messages.jsx:

function Messages() {
const {dispatch, signing, signatures} = useSignatureContext();
const { user } = useUserContext()
const thisPalRef = useRef([]);
useEffect(()=>{
const fetchSignatures = async()=>{
const response = await fetch('/api/signatures/sent', {
method: 'GET',
headers: {
'Authorization': `Bearer ${user.token}`
}
})

const json = await response.json();
if (response.ok) {
json.forEach((mes)=>{
mes.recipient_id === signing._id && thisPalRef.current.push(mes)
})
}
dispatch({type:'SET_SIGNATURES', payload: thisPalRef.current}) //It works fine
}
fetchSignatures()
},[signing._id, user.token, dispatch])

return (
<motion.div 
initial= {{opacity: 0, height:'10%',width:'85%', x:0}}
animate= {{opacity: 1, height:'100%', width:'95%', x:0}}
exit= {{opacity:0, height:'10%',width:'85%', x:0}}
transition={{ duration: 0.2 }}>
<div className="d-flex flex-column align-items-start p-1 pt-4">
<MessageForm />
<div className='prevMsg_container d-flex flex-column align-items-end p-3 mb-5'>
<header className='my-5 align-self-center'>
<h2>Previous Messages</h2>
<hr />
</header>
{
signatures ? signatures.map(mes => {
console.log(signatures)
return <PrevMessages key={mes._id} mes={mes}/>
}) : <small className="text-muted">No messages sent</small>
}

</div>
</div>
</motion.div>
)
}

一个子组件-PrevMessages.jsx

function PrevMessages({mes}) {
const {dispatch} = useSignatureContext();
const {user} = useUserContext();
const handleDeleteMes = async() => {
if (!user) {
return
}
const response = await fetch('/api/signatures/' + mes._id, {
method:'DELETE',
headers: {
'Authorization': `Bearer ${user.token}`
}
})
const json = await response.json();
console.log(json) //it doesn't work
if (response.ok) {
dispatch({type: 'DELETE_SIGNATURE', payload: json}) //it doesnt work
}
}

return  <figure className="text-end">
<blockquote className="blockquote">
<p className='prevMsg_text mt-3 text-end'>{mes.message}</p>
</blockquote>
<figcaption className="blockquote-footer text-end">
<cite title="Sent date">{formatRelative (new Date(mes.updatedAt), new Date())}</cite>
</figcaption>
<IconContext.Provider value={{ color: '#ea1537', className: "delete_icon" }}>
<span className="text-end delete_msg_btn" onClick={() => handleDeleteMes(mes._id)}><RiChatDeleteFill/></span>
</IconContext.Provider>
</figure>

}

和另一个子组件-MessageForm.jsx

function MessageForm() {
const {signing, dispatch} = useSignatureContext();
const { user } = useUserContext()

const [myMessage, setMyMessage] = useState('');
const [error, setError] = useState(null);
const [emptyFields, setEmptyFields] = useState([]);

const handleSubmitMessage = async (e) => {
e.preventDefault()

if (!user) {
setError('You must be logged in')
return
}

const mssg = {
message: myMessage,
recipient: `${signing.name} ${signing.last_name}`,
recipient_id: signing._id,
sender: `${user.name} ${user.last_name}`,
sender_id: user._id,
sender_signature: user.signature
}

const response = await fetch('/api/signatures', {
method: 'POST',
body: JSON.stringify(mssg),
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${user.token}`
}
})

const json = await response.json()

if(!response.ok){
setError(json.error)
setEmptyFields(json.emptyFields)
}
if (response.ok) {
setMyMessage('');
setError(null);
setEmptyFields([]);
console.log('new message sent!', json);
dispatch({type: 'CREATE_SIGNATURE', payload: json}); //works fine
}
}
return (
<>
<h1 className='align-self-center bk_owner_title'>{signing.name}<small className="text-muted">'s Book</small></h1>
<div className="input-group">
<textarea value={myMessage} className={"form-control txtArea pt-4 ps-2 msg_txt_area " + (emptyFields.includes('message') ? ' message_error' : '')} autoFocus onChange={(e)=>setMyMessage(e.target.value)} placeholder={'Dear ' + signing.name + ' ' + signing.last_name + '...'}></textarea>
</div>
<figcaption className='message_footer mx-3 mt-1'>From: {user.signature}</figcaption>
<button type='submit' className='btn btn-success align-self-end' onClick={(e)=>handleSubmitMessage(e)}>Send</button>
{error && <Alert variant='danger' className='mt-3 align-self-center alert_message'>{error}</Alert>}
</>
)
}

这是上下文SignatureContext.jsx

const SignatureContext = createContext();

const signaturesReducer = (mesState, action) => {
switch (action.type) {
case 'SET_SIGNATURES':
return {
signatures: action.payload
}
case 'CREATE_SIGNATURE':
return {
signatures: [action.payload, ...mesState.signatures]
}
case 'DELETE_SIGNATURE':
return {
signatures: mesState.signatures.filter((s) => s._id !== action.payload._id)
}
default:
return mesState
}
}

const SignatureContextProvider = ({children})=> {
const [signing, setSigning] = useState({});
const [mesState, dispatch] = useReducer(signaturesReducer, {
signatures: null
});
return (
<SignatureContext.Provider value={{signing, setSigning, ...mesState, dispatch}}>
{children}
</SignatureContext.Provider>
)
}
export {SignatureContextProvider, SignatureContext, signaturesReducer};

提前谢谢你,任何想法都将不胜感激。

在后端发现问题。控制器函数没有返回JSON响应,因此前端函数无法使用。由于这个原因,它在获取后停止,我使用Express和Mongoose。

这是我以前的控制器功能:

const deleteSignature = async (req, res)=>{
const {id} = req.params
if(!mongoose.Types.ObjectId.isValid(id)) {
return res.status(404).json({error: 'No such signature'})
}
const signature = await Signature.findOneAndDelete({_id: id})
if(!signature) {
return res.status(404).json({error: 'No such signature'})
}
//nothing returning on success
}

这就是我修复的方法

const deleteSignature = async (req, res)=>{
const {id} = req.params
if(!mongoose.Types.ObjectId.isValid(id)) {
return res.status(404).json({error: 'No such signature'})
}
const signature = await Signature.findOneAndDelete({_id: id})
if(!signature) {
return res.status(404).json({error: 'No such signature'})
}
res.status(200).json(signature) //returning json on success
}

它工作得很好。

最新更新