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 นั้นยอดเยี่ยมมาก แต่ฉันจะมุ่งเน้นไปที่การทำให้แอคชั่น redux ทำงานผ่านตัวลดก่อน ผลผลิต root saga ของคุณน่าจะเป็นผลผลิต* เพื่อให้เรียกใช้งาน 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
นั่นคือการกระทำ แต่มีการพิมพ์ผิดมากมายในการทำให้การกระทำนั้นเริ่มทำงาน ฉันขอแนะนำให้เริ่มต้นด้วยกรณีทดสอบพื้นฐานเพื่อให้แน่ใจว่าโค้ดของคุณสามารถส่งการดำเนินการผ่าน redux ได้ตามปกติ โดยไม่ต้องมี redux-saga จากนั้นคุณก็สามารถเริ่มทำความเข้าใจ/ลบคำผิดทั้งหมดได้ ตัวอย่างเช่น คุณต้อง 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