useDispatch в функции handleClick
Как отправить действие при нажатии кнопки? Я хочу отправить действие, которое выполняет асинхронный вызов. Если это невозможно, каков практический способ?
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import allActions from "../redux/actions/index";
import axios from "axios";
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
marginBottom: 10,
},
}));
export default function ChatPreview({ chat }) {
const [secondary, setSecondary] = React.useState(false);
const lastMessageId = chat.messages.slice(-1)[0];
const [message, setMessage] = useState(null);
const [error, setError] = useState(null);
const classes = useStyles();
const user = useSelector((state) => state.user);
const token = localStorage.getItem("IdToken").split(" ")[1];
const dispatch = useDispatch;
//Get otherUser
let otherUser = {};
chat.users.map((user_) => {
if (user_.username !== user.username) otherUser = user_;
});
useEffect(() => {
let headers = { Authorization: `Bearer ${token}` };
axios
.get(`/messages/message/${lastMessageId}`, { headers })
.then((res) => {
setMessage(res.data);
})
.catch((err) => {
setError(err);
});
}, []);
let primary = false;
if (user && message) {
if (user._id === message.author) primary = true;
}
const handleClick = () => {
dispatch(allActions.inboxActions.deleteChat(chat._id, token));
};
const chatPreviewMarkup =
message && user ? (
<List>
<ListItem>
<ListItemAvatar>
<Avatar alt={otherUser.username} src={otherUser.avatar} />
</ListItemAvatar>
<ListItemText
primary={
primary ? (message.read ? "read" : "unread") : message.content
}
secondary={secondary ? "Secondary text" : null}
/>
<ListItemSecondaryAction>
<IconButton edge="end" aria-label="delete">
<DeleteIcon onClick={handleClick} />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
</List>
) : (
<p>...loading</p>
);
return chatPreviewMarkup;
}
возвращает следующую ошибку:
Ошибка: неверный вызов ловушки. Хуки могут быть вызваны только внутри тела функционального компонента. Это могло произойти по одной из следующих причин:
- У вас могут быть несовпадающие версии React и средства визуализации (например, React DOM)
- Вы можете нарушить правила ловушек
- У вас может быть несколько копий React в одном приложении.
2 ответа
Вам нужно позвонить
useDispatch()
вне обратного вызова, потому что перехватчики должны находиться на верхнем уровне компонента.
Вы почти сделали это, но вас сбила опечатка. Вам нужно изменить
const dispatch = useDispatch;
к
const dispatch = useDispatch();
Отсутствующие скобки означают, что вы на самом деле не звоните
useDispatch
пока внутри твоего
handleClick
. Переменная
dispatch
это сам хук, а не возвращаемое значение, поэтому, когда вы вызываете
dispatch(allActions...)
ты действительно звонишь
useDispatch(allActions...)
и появляется ошибка.
Как это
function MyComponent() {
const dispatch = useDispatch()
const handleClick = () => {
dispatch(actionCreator())
}
return (
<button onClick={handleClick}>
Click me
</button>
)
}