Пытаюсь использовать redux-thunk, но выдает ошибку, хотя мне кажется, что все в порядке

Итак, я следую руководству, в котором реализован редукционный преобразователь, и сделал все, как показано в видео, но все равно получаю эту ошибку:

Ошибка: действия должны быть простыми объектами. Вместо этого фактический тип был: «Обещание». Возможно, вам потребуется добавить промежуточное программное обеспечение в настройки вашего магазина, чтобы обрабатывать отправку других значений, например «redux-thunk» для обработки функций отправки.

Вот как выглядит код:

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
    
import reducers from './reducers';
    
import App from './App';
    
const store = createStore(reducers, applyMiddleware(thunk));
    
ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, 
    document.getElementById('root')
);

Вот действие

actions/posts.js

export const createPost = (post) => async (dispatch) => {
    try {
        const { data } = await api.createPost(post);

        dispatch({ type: 'CREATE', payload: data });
    } catch (error) {
        console.log(error);
    }
}

Редуктор:

const reducer = (posts = [], action) => {
    switch (action.type) {
        case 'FETCH_ALL':
            return action.payload;
        case 'CREATE':
            return [ ...posts, action.payload];
        default:
            return posts;
    }
}

export default reducer;

И файл, в котором возникает ошибка:

import React, { useState } from 'react';
import { TextField, Button, Typography, Paper } from '@material-ui/core';
import FileBase from 'react-file-base64';
import { useDispatch } from 'react-redux';

import useStyles from './styles';
import { createPost } from '../../api';

export default function Form() {
    const [postData, setPostData] = useState({
        creator: '', 
        title: '', 
        message: '', 
        tags: '', 
        selectedFile: ''
    });
    const classes = useStyles();
    const dispatch = useDispatch();

    const handleSubmit = (e) => {
        e.preventDefault();

        dispatch(createPost(postData));
    }

    const clear = () => {

    }

    return (
        <Paper className={classes.paper}>
            <form autoComplete="off" noValidate className={`${classes.root} ${classes.form}`} onSubmit={handleSubmit}>
            <Typography variant="h6">Creating a Memory</Typography>
            <TextField 
                name="creator"
                variant="outlined"
                label="Creator"
                fullWidth
                value={postData.creator}
                onChange={(e) => setPostData({ ...postData, creator: e.target.value })}
            />
            <TextField 
                name="title"
                variant="outlined"
                label="Title"
                fullWidth
                value={postData.title}
                onChange={(e) => setPostData({ ...postData, title: e.target.value })}
            />
            <TextField 
                name="message"
                variant="outlined"
                label="Message"
                fullWidth
                value={postData.message}
                onChange={(e) => setPostData({ ...postData, message: e.target.value })}
            />
            <TextField 
                name="tags"
                variant="outlined"
                label="Tags"
                fullWidth
                value={postData.tags}
                onChange={(e) => setPostData({ ...postData, tags: e.target.value })}
            />
            <div className={classes.fileInput}>
                <FileBase 
                    type="file"
                    multiple={false}
                    onDone={({base64}) => setPostData({ ...postData, selectedFile: base64 })}
                />
            </div>
            <Button className={classes.buttonSubmit} variant="contained" color="primary" size="large" type="submit" fullWidth>Submit</Button>
            <Button variant="contained" color="secondary" size="small" onClick={clear} fullWidth>Clear</Button>
            </form>
        </Paper>
    )
}

Я действительно не вижу здесь проблемы, я был бы признателен, если бы кто-нибудь просветил меня! Спасибо!!:)


person reClicked    schedule 15.06.2021    source источник
comment
Какой у вас ./reducers файл? Вы использовали combReducer?   -  person Tasos Bu    schedule 15.06.2021
comment
Да, вот как это выглядит: import { combineReducers } from "redux"; import posts from './posts'; export default combineReducers({ posts });   -  person reClicked    schedule 15.06.2021
comment
Можешь поделиться кодом api.createPost(post)   -  person Rajdeep Debnath    schedule 15.06.2021
comment
Мне все кажется правильным. Использует ли ваше приложение горячую перезагрузку? Вы пытались убить запуск npm и запустить его снова?   -  person Tasos Bu    schedule 15.06.2021
comment
Я думаю, что ваша проблема может быть дубликатом этого сообщения: stackoverflow.com/a/54066862/5605822   -  person Tasos Bu    schedule 15.06.2021
comment
@TasosBu Да, попробовал прямо сейчас, но это то же самое   -  person reClicked    schedule 15.06.2021
comment
@RajdeepDebnath export const createPost = (newPost) => axios.post(url, newPost); вот как это выглядит   -  person reClicked    schedule 15.06.2021
comment
Можешь попробовать удалить рассылку из handleSubmit и просто сделать: createPost(postData)?   -  person Tasos Bu    schedule 15.06.2021
comment
все выглядит нормально, не уверен, что блок try catch в post.js может быть проблемой, поскольку не все пути кода возвращают ожидаемый формат. Можно удалить и попробовать. Может глупое предложение.   -  person Rajdeep Debnath    schedule 15.06.2021
comment
@TasosBu Я прочитал этот вопрос, но мой код выглядит так, как в ответе, который был принят, поэтому я не знаю, в чем проблема.   -  person reClicked    schedule 15.06.2021
comment
@RajdeepDebnath попытался удалить блок try catch, но возникла та же ошибка.   -  person reClicked    schedule 15.06.2021
comment
Итак, что произойдет, если блок try выдаст ошибку? журнал консоли произойдет в блоке catch, и тогда ничего не будет возвращено.   -  person Rajdeep Debnath    schedule 15.06.2021
comment
@reClicked вы можете console.log после этой строки const { data } = await api.createPost(post); проверить, получаете ли вы ожидаемые данные обратно   -  person Rajdeep Debnath    schedule 15.06.2021
comment
Спасибо, но я нашел ошибку, которую я сделал. Я импортировал неправильную функцию createPost, хе-хе. Но спасибо за множество советов!   -  person reClicked    schedule 15.06.2021


Ответы (2)


В вашем методе createStore есть две ошибки.

  1. Первый параметр createStore — это корневой редуктор, и это нормально. Но второй параметр должен быть начальным состоянием, и вы передаете applyMiddleware вместо начального состояния.
  2. Вы должны передать массив промежуточных программ методу applyMiddleware
// do like this
const store = createStore(reducers, {}, applyMiddleware([thunk]));

// not like this
const store = createStore(reducers, applyMiddleware(thunk));
person Haseeb Anwar    schedule 15.06.2021
comment
Пробовал обоими способами, но все равно не повезло :/ Но все же спасибо за ответ! - person reClicked; 15.06.2021
comment
о, нашел твою ошибку. Только что обновленный ответ - person Haseeb Anwar; 15.06.2021

Спасибо всем, кто ответил на вопрос! Оказывается, я импортировал неправильную функцию createPost, глупый я! К счастью, теперь все работает!

person reClicked    schedule 15.06.2021