Bagaimana cara mendapatkan sesuatu dari negara / toko di dalam fungsi redux-saga?

123

Bagaimana cara mengakses status redux di dalam fungsi saga?

Jawaban singkat:

import { select } from 'redux-saga/effects';
...
let data = yield select(stateSelectorFunction);
Adam Tal
sumber

Jawaban:

211

Seperti yang sudah dikatakan @markerikson, redux-sagamengekspos API yang sangat berguna select()untuk memanggil selectorstatus agar beberapa bagiannya tersedia di dalam saga.

Untuk contoh Anda, penerapan sederhana dapat berupa:

/*
 * Selector. The query depends by the state shape
 */
export const getProject = (state) => state.project

// Saga
export function* saveProjectTask() {
  while(true) {
    yield take(SAVE_PROJECT);
    let project = yield select(getProject); // <-- get the project
    yield call(fetch, '/api/project', { body: project, method: 'PUT' });
    yield put({type: SAVE_PROJECT_SUCCESS});
  }
}

Selain dokumen yang disarankan oleh @markerikson, ada video tutorial yang sangat bagus oleh D. Abramov yang menjelaskan cara menggunakan selectorsRedux. Periksa juga utas menarik ini di Twitter.

NickGnd
sumber
3
Persis apa yang saya inginkan .. Saya tidak percaya saya melewatkannya
Adam Tal
30

Untuk itulah fungsi "selector". Anda memberikan mereka seluruh pohon negara bagian, dan mereka mengembalikan sebagian negara bagian. Kode yang memanggil pemilih tidak perlu tahu di mana dalam keadaan itu data itu, hanya saja itu dikembalikan. Lihat http://redux.js.org/docs/recipes/ComputingDerivedData.html untuk beberapa contoh.

Dalam saga, select()API dapat digunakan untuk menjalankan selektor.

markerikson
sumber
Sangat menarik bagaimana ini ditulis 3,5 jam sebelum jawaban diterima, tetapi tidak memberikan contoh, sehingga gagal diterima. Terima kasih lagian!
Aleksandar
1
@ Casing - Saya setuju! Tetapi ini bukan tentang seberapa cepat Anda menjawab pertanyaan di sini, tetapi seberapa baik jawaban Anda. Saya pikir jawaban harus dibuat sederhana dan mudah dibaca. Jawaban ini tidak sesuai dengan itu dan jawaban yang diterima jauh lebih mudah dipahami.
Adam Tal
@AdamTal ya, saya setuju :)
Aleksandar
2

Saya menggunakan eventChannel untuk mengirimkan tindakan dari callback dalam fungsi generator

import {eventChannel} from 'redux-saga';
import {call, take} from 'redux-saga/effects';

function createEventChannel(setEmitter) {
    return eventChannel(emitter => {
        setEmitter(emitter)
        return () => {

        }
      }
    )
}

function* YourSaga(){
    let emitter;
    const internalEvents = yield call(createEventChannel, em => emitter = em)

    const scopedCallback = () => {
        emitter({type, payload})
    }

    while(true){
        const action = yield take(internalEvents)
        yield put(action)
    }
}
yardenapp
sumber