React-Redux: Дії мають бути звичайними об’єктами. Використовуйте власне проміжне програмне забезпечення для асинхронних дій


84

Невідпрацьоване відхилення (помилка): дії повинні бути звичайними об’єктами. Використовуйте власне проміжне програмне забезпечення для асинхронних дій.

Я хотів додавати коментарі до кожного повідомлення. Отже, коли запускаються публікації отримання, я хочу зателефонувати API отримання коментарів для всіх повідомлень.

export function bindComments(postId) {
  return API.fetchComments(postId).then(comments => {
    return {
      type: BIND_COMMENTS,
      comments,
      postId
    }
  })
}

Відповіді:


65

Ви повинні відправити після закінчення запиту на асинхронізацію.

Це буде працювати:

export function bindComments(postId) {
    return function(dispatch) {
        return API.fetchComments(postId).then(comments => {
            // dispatch
            dispatch({
                type: BIND_COMMENTS,
                comments,
                postId
            });
        });
    };
}

4
Це згадується нижче, але для того, щоб це працювало, вам потрібно мати проміжне програмне забезпечення для
зменшення розміру

1
@sadiq, чому обов’язково надсилати акцію? У мене була та сама проблема з асинхронною дією, яку я не визначив як "асинхронна відправка", хоча я не хотів нічого відправляти в магазин.
Сорагім

13

Для майбутніх шукачів, котрі могли пропустити такі прості деталі, як я, у моєму випадку я просто забув назвати свою функцію дії дужками.

actions.js:

export function addNewComponent() {
  return {
    type: ADD_NEW_COMPONENT,
  };
}

myComponent.js:

import React, { useEffect } from 'react';
import { addNewComponent } from '../../redux/actions';

  useEffect(() => {
    dispatch(refreshAllComponents); // <= Here was what I've missed.
  }, []);

Я забув надіслати функцію дії за допомогою (). Отже, це вирішило моє питання.

  useEffect(() => {
    dispatch(refreshAllComponents());
  }, []);

Знову ж таки, це може не мати нічого спільного з проблемою OP, але я сподіваюся, що допомагаю людям із тією ж проблемою, що і моя.


1
Дякую за це. Легко пропустити. Не роблячи ніяких асинхронних речей, тому я знав, що це щось просте, чого я пропустив!
Тейлор А. Ліч

11

Ви не можете використовувати вибірку в діях без проміжного програмного забезпечення. Дії повинні бути звичайними об'єктами. Ви можете використовувати проміжне програмне забезпечення, таке як redux-thunk або redux-saga, щоб зробити вибірку, а потім надіслати іншу дію.

Ось приклад дії асинхронізації за допомогою проміжного програмного забезпечення redux-thunk.

export function checkUserLoggedIn (authCode) {
 let url = `${loginUrl}validate?auth_code=${authCode}`;
  return dispatch => {
    return fetch(url,{
      method: 'GET',
      headers: {
        "Content-Type": "application/json"
      }
      }
    )
      .then((resp) => {
        let json = resp.json();
       if (resp.status >= 200 && resp.status < 300) {
          return json;
        } else {
          return json.then(Promise.reject.bind(Promise));
        }
      })
      .then(
        json => {
          if (json.result && (json.result.status === 'error')) {
            dispatch(errorOccurred(json.result));
            dispatch(logOut());
          }
          else{
            dispatch(verified(json.result));
          }
        }
      )
      .catch((error) => {
        dispatch(warningOccurred(error, url));
      })
  }
}

На жаль, я думав, що ви не використовуєте проміжне програмне забезпечення. там була проблема відправки, що @sadiq згадав про це.
Сінапч

6

Використовуйте функції Arrow, це покращує читабельність коду. Не потрібно нічого повертати API.fetchComments, виклик Api є асинхронним, коли запит завершено then, отримає відповідь, там потрібно просто dispatchввести і дані.

Нижче код виконує ту саму роботу, використовуючи функції стрілок.

export const bindComments = postId => {
  return dispatch => {
    API.fetchComments(postId).then(comments => {
      dispatch({
        type: BIND_COMMENTS,
        comments,
        postId
      });
    });
  };
};

6

Помилка просто просить вас вставити проміжне програмне забезпечення, яке між собою допоможе обробляти асинхронні операції.

Ви можете зробити це, виконавши:

нм / хв я скорочую

        Inside index.js

import thunk from "redux-thunk" 
        
...createStore(rootReducers, applyMiddleware(thunk));

Тепер асинхронні операції працюватимуть усередині ваших функцій.


2

У мене була та ж проблема, що я пропустив додавання composeEnhancers. Як тільки це буде налаштовано, ви зможете поглянути на творців дій. Ви отримуєте цю помилку, коли це також не налаштовано.

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(
  rootReducer,
  composeEnhancers(applyMiddleware(thunk))
);

0

Визначення дії

const selectSlice = () => {
  return {
    type: 'SELECT_SLICE'
  }
};

Дія відправлення

store.dispatch({
  type:'SELECT_SLICE'
});

Переконайтесь, що визначена структура об’єкта дії така ж, як і дія, що надсилається. У моєму випадку під час диспетчерської дії тип не був присвоєний властивості type.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.