2016-04-13 5 views
6

मैं क्या जरूरत के लिए: एक controlled component कि एक input[type="search"] है। कहने के बाद, उस घटक में कोई दूसरा बदलाव नहीं है, मैं उस खोज को निष्पादित करने के लिए एक HTTP कॉल भेजना चाहता हूं और परिणाम किसी अन्य घटक में दिखाया गया है।सही रास्ता redux में राज्य के आधार पर HTTP कॉल थ्रोटल और प्रतिक्रिया

मैं इसे कैसे किया है: जब भी मैं dispatch(setSearch(str)); फोन मैं dispatch(displaySearch(false)); को एक फोन करना है और फिर _.throttledispatch(displaySearch(true));

के लिए एक कॉल यह मेरे लिए लगता है कि घटक में काम की इस तरह कर रही है वह सही नहीं है , लेकिन मैं Redux में एक reducer में ऐसा करने के लिए एक तरीका नहीं सोच सकता।

+0

आप (अपने सभी API कॉल के लिए की तरह) या केवल इस घटक के लिए अपने सभी आवेदन के लिए someting वैश्विक करना चाहते हैं? – KeitIG

+0

मैं इसे एप्लिकेशन के इस खंड के भीतर अन्य घटकों में उपयोग करने के लिए देख सकता था। – Dave

+0

देखें http://stackoverflow.com/questions/23123138/perform-debounce-in-react-js/28046731#28046731 –

उत्तर

4

आपके पास इसे हल करने के लिए अलग-अलग विकल्प हैं।

1. Debounce एक घटक स्तर

इस पर अपनी कार्रवाई सरल तरीका है। जब इनपुट एक परिवर्तन को ट्रिगर करता है, तो यह को कॉल करता है setSearch का एक अस्वीकृत संस्करण सर्वर कॉल में देरी करता है।

import * as React from "react" 
import {connect} from "react-redux" 
import {setSearch} from "./actions" 

export default connect(
    null, 
    function mapDispatchToProps(dispatch) { 
    const setSearch_ = _.debounce(q => dispatch(setSearch(q)), 1000) 
    return() => ({setSearch: setSearch_}) 
    } 
)(
    function SearchForm(props) { 
    const {setSearch} = props 
    return (
     <input type="search" onChange={setSearch} /> 
    ) 
    } 
) 

2. redux-saga

का उपयोग कर यह दृष्टिकोण Debounce अधिक बॉयलरप्लेट की आवश्यकता है, लेकिन आप कार्यप्रवाह से अधिक एक बहुत अधिक नियंत्रण देता है। सागा का उपयोग करके हम SET_SEARCH कार्रवाई को अवरुद्ध करते हैं, इसे अस्वीकार करते हैं, एपीआई को कॉल करते हैं और परिणाम युक्त एक नई क्रिया भेजते हैं।

import {call, cancel, fork, put, take} from "redux-saga/effects" 
import {setSearchResults} from "./actions" 
import {api} from "./services" 
import {delay} from "./utils" 

export default function* searchSaga() { 
    yield [ 
    // Start a watcher to handle search workflow 
    fork(watchSearch) 
    ] 
} 

function* watchSearch() { 
    let task 

    // Start a worker listening for `SET_SEARCH` actions. 
    while (true) { 
    // Read the query from the action 
    const {q} = yield take("SET_SEARCH") 

    // If there is any pending search task then cancel it 
    if (task) { 
     yield cancel(task) 
    } 

    // Create a worker to proceed search 
    task = yield fork(handleSearch, q) 
    } 
} 

function* handleSearch(q) { 
    // Debounce by 1s. This will lock the process for one second before 
    // performing its logic. Since the process is blocked, it can be cancelled 
    // by `watchSearch` if there are any other actions. 
    yield call(delay, 1000) 

    // This is basically `api.doSearch(q)`. The call should return a `Promise` 
    // that will resolve the server response. 
    const results = yield call(api.doSearch, q) 

    // Dispatch an action to notify the UI 
    yield put(setSearchResults(results)) 
} 
+1

खराब विचार: 'mapDispatchToProps' पर बहस फ़ंक्शन बनाना मतलब है कि बहस समारोह हर बार राज्य को फिर से बनाया जाएगा परिवर्तन, जिसका अर्थ है कि इसे वास्तव में बहस नहीं किया जाएगा। इसके अलावा रेडक्स-सागा के लिए उस पर एक डॉक्टर है: http://yelouafi.github.io/redux-saga/docs/recipes/index.html –

+0

@ सेबेस्टियन लॉर्बर आप 'mapDispatchToProps' के बारे में सही थे। मैंने अपना जवाब अपडेट कर लिया है, अब यह मामला नहीं है, धन्यवाद! और हाँ, मेरा नमूना कोड रेडक्स गाथा के व्यंजनों से उधार लिया गया था। – Florent

1

एसोसिएट delay और takeLatest:

import { all, takeLatest, call } from 'redux-saga/effects'; 
import { delay } from 'redux-saga'; 


function* onSearch(action) { 
    yield call(delay, 1000); // blocks until a new action is 
          // triggered (takeLatest) or until 
          // the delay of 1s is over 

    const results = yield call(myFunction); 
} 

function* searchSagas() { 
    yield all([ 
    // ... 
    takeLatest(ON_SEARCH, onSearch), 
    ]); 
} 

export default [searchSagas]; 
संबंधित मुद्दे