Làm thế nào để lấy một cái gì đó từ trạng thái / lưu trữ bên trong một hàm redux-saga?


123

Làm cách nào để truy cập trạng thái redux bên trong một hàm saga?

Câu trả lời ngắn:

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

Câu trả lời:


211

Như @markerikson đã nói, redux-sagacho thấy một API rất hữu ích select()để gọi một selectortrạng thái trên để đưa một số phần của nó có sẵn bên trong saga.

Đối với ví dụ của bạn, một triển khai đơn giản có thể là:

/*
 * 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});
  }
}

Ngoài tài liệu được gợi ý bởi @markerikson, có một video hướng dẫn rất hay của D. Abramov giải thích cách sử dụng selectorsvới Redux. Cũng kiểm tra chủ đề thú vị này trên Twitter.


3
Chính xác những gì tôi muốn .. Tôi không thể tin tôi đã bỏ lỡ nó
Adam Tal

30

Đây là chức năng của "bộ chọn". Bạn chuyển cho chúng toàn bộ cây trạng thái và chúng trả về một số phần của trạng thái. Mã gọi bộ chọn không cần biết dữ liệu đó ở trạng thái nào, chỉ cần nó được trả về. Xem http://redux.js.org/docs/recipes/ComputingDerivedData.html để biết một số ví dụ.

Trong một câu chuyện, select()API có thể được sử dụng để thực thi một bộ chọn.


Thật thú vị khi điều này được viết 3,5 giờ trước câu trả lời được chấp nhận, nhưng nó không cung cấp ví dụ, vì vậy nó không được chấp nhận. Dù sao cũng cảm ơn bạn!
Aleksandar

1
@Casper - Tôi đồng ý! Nhưng không phải ở đây bạn trả lời câu hỏi nhanh như thế nào mà là câu trả lời của bạn hay như thế nào. Tôi nghĩ rằng câu trả lời phải được giữ đơn giản và dễ đọc. Câu trả lời này không khớp với câu trả lời đó và câu trả lời được chấp nhận dễ hiểu hơn nhiều.
Adam Tal

@AdamTal vâng, tôi đồng ý :)
Aleksandar

2

Tôi đã sử dụng eventChannel để gửi một hành động từ một lệnh gọi lại trong hàm trình tạo

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)
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.