Redux Saga: как вставить обратный вызов

У меня есть этот код в sagas.js.

import { put, takeLatest } from "redux-saga/effects";
import { getArticles } from "../scripts/resources/articles";
import { GET_ARTICLES, SHOW_MATCHES } from "./constants";


function getMatches(action) {
    const { searchValue } = action;
    getArticles(searchValue, (matches) => {
        console.log(matches)
        put({ type: SHOW_MATCHES, payload: matches })
    })
}

export default function* rootSaga() {
    yield takeLatest(GET_MATCHES, getMatches);
}

А это функция getArticles.

export function getArticles(input, callBack) {
    setTimeout(() => {
        callBack(filterArticles(input));
    }, 300);
};

Помещение внутри обратного вызова на самом деле не отправляет действие, так как я не дохожу до случая в редюсере. Как я могу отправить это действие?


person Matt    schedule 21.06.2018    source источник
comment
Пара советов, чтобы начать с правильного пути: отправка действий обрабатывается полностью независимо от саги, поэтому использование этого в качестве базового варианта для тестирования — это то, с чего нужно начать. Также в коде поста пока нет действия или отправки действия. Redux-saga великолепна, но я бы сосредоточился на том, чтобы действие редукции сначала работало с редуктором. выход вашей корневой саги, вероятно, должен быть yield*, чтобы он всегда выполнял takeLatest. Вы, вероятно, хотите function* getMatches, чтобы getMatches была функцией генератора, чтобы работали эффекты от redux-saga.   -  person The Brofessor    schedule 21.06.2018
comment
{ type: SHOW_MATCHES, payload: matches } Это не акция?   -  person Matt    schedule 21.06.2018
comment
это действие, но есть много опечаток на пути запуска этого действия. Я рекомендовал начать с базового теста, чтобы убедиться, что ваш код может нормально отправлять действие через избыточность, без избыточной саги. Оттуда вы можете начать понимать / удалять все опечатки. Например, вам нужно, чтобы getMatches была функцией-генератором, чтобы получить эффект put. вам также необходимо явно указать генератору yield эффект, а не просто вызывать put. т.е. yield put({ type: "EXAMPLE", payload: data});   -  person The Brofessor    schedule 21.06.2018
comment
В этом случае я не могу вызвать yield с put, потому что я передаю его getArticles, который не является генератором, поэтому он выдает ошибку. Моя следующая мысль - передать функцию dispatch в сагу, но я не уверен, как это сделать.   -  person Matt    schedule 21.06.2018
comment
Если вы хотите, чтобы ваша сага запускалась после некоторой задержки, используйте дроссель из саги/эффектов.   -  person user93    schedule 21.06.2018
comment
Возможный дубликат Как получить результат в redux-saga внутри обратный звонок?   -  person Alex    schedule 21.06.2018


Ответы (1)


Во-первых, простой вызов put() не передаст эффект размещения в канал саги, если ему не предшествует yield.

Во-вторых, yield должен использоваться внутри функции-генератора, поэтому вам нужно изменить вызывающего yield put(...) и вызывающего его вызывающего объекта на форму функции-генератора, то есть

function *(){
  yield anotherGeneratorFunction()
}

Следующий измененный код просто работает

const { createStore, applyMiddleware } =require('redux')
const createSagaMiddleware =require('redux-saga').default
const { takeLatest ,take,put}=require('redux-saga/effects') 
const {delay} =require('redux-saga')
const sagaMiddleware = createSagaMiddleware()
const reducer=(state=[],action)=>{return [...state,action.type];}
const store = createStore(
    reducer,
    applyMiddleware(sagaMiddleware)
)

function * getMatches(action) {
    const { searchValue } = action;
    yield getArticles(searchValue, function * (matches) {
        console.log(matches)
        yield put({ type: 'SHOW_MATCHES', payload: matches })
    })
}

function * getArticles(input, callBack) {
    yield delay(300)
    yield callBack(filterArticles(input));
};

function filterArticles(input){
    return ['artical1','artical2']
}

function* rootSaga() {
    yield takeLatest('GET_MATCHES', getMatches);
}

sagaMiddleware.run(rootSaga)

store.dispatch({type:'GET_MATCHES',searchValue: 'test'})
setTimeout(() => {
    console.log(store.getState())
}, 1000);

Это выведет

[ 'artical1', 'artical2' ]
[ '@@redux/INIT5.m.i.0.z.9', 'GET_MATCHES', 'SHOW_MATCHES' ]
person Benjamin    schedule 22.06.2018