Redux Saga: Cara memasukkan panggilan balik

Saya memiliki kode ini di 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);
}

Dan ini adalah fungsi getArticles.

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

Panggilan balik yang dimasukkan ke dalam tidak benar-benar mengirimkan tindakan karena saya tidak mencapai kasus di peredam. Bagaimana cara mengirimkan tindakan ini?


person Matt    schedule 21.06.2018    source sumber
comment
Beberapa tip untuk memulai di jalur yang benar: pengiriman tindakan ditangani sepenuhnya independen dari sebuah saga, jadi menggunakannya sebagai kasus dasar untuk menguji adalah awal yang baik. Juga belum ada tindakan atau pengiriman tindakan dalam kode di postingan. Redux-saga luar biasa, tapi saya akan fokus untuk membuat tindakan redux diterapkan ke peredam terlebih dahulu. hasil saga root Anda mungkin harus berupa hasil* sehingga selalu mengeksekusi takeLatest. Anda mungkin ingin function* getMatches agar getMatches menjadi fungsi generator agar efek dari redux-saga berfungsi.   -  person The Brofessor    schedule 21.06.2018
comment
{ type: SHOW_MATCHES, payload: matches } Ini bukan suatu tindakan?   -  person Matt    schedule 21.06.2018
comment
itu adalah sebuah tindakan, namun ada banyak kesalahan ketik dalam cara mengaktifkan tindakan tersebut. Saya merekomendasikan memulai dengan kasus uji dasar untuk memastikan kode Anda dapat mengirimkan tindakan melalui redux secara normal, tanpa redux-saga. Dari situ Anda bisa mulai memahami/menghilangkan semua kesalahan ketik. Misalnya Anda memerlukan getMatches menjadi fungsi generator untuk menghasilkan efek put. Anda juga perlu secara eksplisit memberi tahu generator untuk yield efeknya, bukan hanya memanggil put. Yaitu. yield put({ type: "EXAMPLE", payload: data});   -  person The Brofessor    schedule 21.06.2018
comment
Dalam hal ini saya tidak dapat memanggil yield dengan put karena saya meneruskannya ke getArticles yang bukan generator sehingga menimbulkan kesalahan. Pikiran saya selanjutnya adalah meneruskan fungsi dispatch ke dalam saga tetapi saya tidak yakin bagaimana melakukannya.   -  person Matt    schedule 21.06.2018
comment
Jika Anda ingin saga Anda diaktifkan setelah beberapa penundaan, gunakan throttle dari saga/efek   -  person user93    schedule 21.06.2018
comment
Kemungkinan duplikat Cara menghasilkan yang dimasukkan ke dalam redux-saga di dalamnya panggilan balik?   -  person Alex    schedule 21.06.2018


Jawaban (1)


Pertama, memanggil put() saja tidak akan memberikan efek ke saluran saga kecuali didahului oleh yield.

Kedua, yield harus digunakan di dalam fungsi generator, jadi Anda perlu mengubah pemanggil yield put(...) dan pemanggil pemanggilnya ke bentuk fungsi generator, yaitu

function *(){
  yield anotherGeneratorFunction()
}

Kode yang diubah berikut ini berfungsi

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);

Ini akan menghasilkan

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