У меня есть приложение React/Redux/Node, которое отправляет запрос на обновление пользователя:
client/src/components/pages/AlignmentPage.tsx:
const AlignmentPage = () => {
const dispatch = useAppDispatch();
const [alignment, setAlignment] = useState("");
const user: User | null = useAppSelector(
(state: RootState) => state.userData.user
);
const handleSetAlignment = (value: string) => {
setAlignment(value);
displayNewAlignment(value);
if (user) {
console.info("in AlignmentPage.tsx:", { alignment: value });
dispatch(updateUser(user._id, { alignment: value }));
}
};
...
В моем действии Redux мы вызываем конечную точку PUT для пользователя:
export const updateUser = (userId: string, data: any) => async (dispatch: any) => {
try {
dispatch(setLoadingAction(true));
const response = await fetch(`http://localhost:5000/api/user/${userId}`, {
method: 'PUT',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
const updatedData = await response.json();
dispatch(updateUserAction(updatedData.user));
} catch (error) {
dispatch(setErrorAction('error updating user!'));
}
}
Конечная точка контроллера выглядит следующим образом:
exports.updateUser = asyncHandler(async (req: any, res: any, next: any) => {
const { userId } = req.params;
console.info(req.body)
const data = req.body;
const user = await updateUser(userId, data);
res.status(200).json({ user });
});
По какой-то причине в контроллере я могу нормально выйти из параметра userId. Но тело всегда возвращает undefined и поэтому хранилище Redux и Document в Mongo не обновляются. Я могу успешно регистрировать «данные» до вызова const response = await fetch(http://localhost:5000/api/user/${userId}" в действии Redux. Регистратор updatedData возвращает исходный объект MongoDB, но без обновленного поля («выравнивание»):
Object { user: {…} }
user: Object { _id: "65d73ae14d1a69c64d6787e6", ipAddress: "::ffff:127.0.0.1", createdAt: "2024-02-22T12:15:29.745Z", … }
__v: 0
_id: "65d73ae14d1a69c64d6787e6"
alignment: ""
createdAt: "2024-02-22T12:15:29.745Z"
ipAddress: "::ffff:127.0.0.1"
Такое впечатление, что что-то мешает отправить тело на контроллер. Я не уверен, так ли я настраиваю роутер или что. Я где-то читал, что это может быть связано с тем, что на стороне сервера не установлено промежуточное программное обеспечение bodyParser, поэтому я реализовал это в своем файле server.ts, но, похоже, это не решило проблему.
(async () => {
const port = env.PORT;
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/api/user', userRouter);
try {
app.listen(port, () => {
db.on("error", console.error.bind(console, "connection error:"));
db.on("connected", function () {
console.info("Connected to MongoDB");
});
console.info(`Server started at http://localhost:${port}`);
});
} catch (err) {
const error = new Error("Request failed");
console.info(err);
throw error;
} finally {
console.info("Server started");
}
})();
api/src/routes/user.ts:
router.get("/api/user", userController.getUser);
router.put("/api/user/:userId", userController.updateUser);
export { router };
Добавлены скриншоты логгеров и полезной нагрузки redux:





Я понял.
Мне нужно было передать express.json() в качестве аргумента при вызове конечной точки пользовательского контроллера.
api/src/routes/user.ts:
router.put("/api/user/:userId", express.json(), userController.updateUser);
api/src/controllers/user.ts:
exports.updateUser = asyncHandler(async (req: any, res: any, next: any) => {
const { userId } = req.params;
const data = req.body;
const user = await updateUser(userId, data);
res.status(200).json({ user });
});
Данные успешно обновляются :)