2015-12-09 5 views
0

Я хочу, чтобы представление всегда обновлялось с результатом последнего вызова searchWiki(). Я использовал модуль, который разрешает повторные вызовы $.ajax на значение, возвращаемое последним вызовом.Реакция setState с несколькими вызовами AJAX

Он по-прежнему не синхронизирован и показывает результат предыдущих вызовов. Я предполагаю, что это потому, что setState is async? Как сохранить синхронизацию двух асинхронных операций?

Кроме того, я понимаю, что я должен где-то дебютировать, но я не уверен, что я должен отбросить. handleChange, searchWiki или latestAjax?

Демо-версия: http://codepen.io/prashcr/pen/obXvWv
Попробуйте ввести материал, а затем обратно, чтобы увидеть, что я имею в виду.

компонент поиска

<div style={style}> 
    <input 
    value={this.props.search} 
    // this calls searchWiki with e.target.value 
    onInput={this.handleChange} 
    /> 
</div> 

Википоиска функция родительского компонента

searchWiki (search) { 
    console.log('searchWiki called with: ' + search); 
    if (!search) { 
    this.setState({results: []}); 
    } 
    else { 
    // "latest" taken from https://github.com/bjoerge/promise-latest 
    let latestAjax = latest($.ajax); 
    let options = { 
     url: this.props.url + search, 
     dataType: 'jsonp' 
    }; 
    latestAjax(options) 
    .then(data => { 
     var results = data.query.search.map(res => { 
     res.url = 'http://en.wikipedia.org/wiki/' + encodeURIComponent(res.title); 
     return res; 
     }); 
     this.setState({results: results}); 
    }) 
    .error(e => console.log(e.message)); 
    } 
} 

ответ

1

handleChange функция является слишком общим, чтобы быть с подавлением дребезга контактов закодированного значения, как вы можете использовать этот компонент поиска в другом месте. Тем не менее, вы по-прежнему хотите как можно скорее поймать повторяющееся действие и обеспечить, чтобы он никогда не делал ненужной работы.

Поэтому я предлагаю вам отказаться от функции handleChange с опциональной опорой, по умолчанию 0мс.

getDefaultProps() { 
    return { 
    debounce: 0 
    }; 
}, 
render() { 
    // ... 
    return (
    <div style={style}> 
     <input 
     // ... 
     onInput={debounce(this.handleChange, this.props.debounce)}/> 
    </div> 
); 
} 

Затем убедитесь, что вы передали эту опору, когда хотите отменить обработчик.

<Search onSearch={this.searchWiki} debounce={1000} /> 

другая Ваша проблема происходит потому, что вы вызываете latest внутри вашей searchWiki функции, и вы только вызовите функцию возвращенного один раз! Каждый раз, когда вы вызываете searchWiki, вы создаете новую функцию latestAjax.

Для его работы вам нужно будет вызвать возвращенную функцию несколько раз.

Это означает определение обернутой функции $.ajax вне функции searchWiki.

latestAjax: latest($.ajax), 
searchWiki(search) { 
    // ... 
    this.latestAjax(options) 
    .then(data => { 

    }); 
} 
+0

Хм, это имеет смысл, спасибо! Были ли у вас какие-либо предложения относительно моей другой проблемы? т. е. обновить состояние моего другого представления с результатами текущего состояния «Поиск» –

+0

Ах, глупо меня. Теперь часть AJAX работает свободно! Последнее, что хороший способ установить 'this.state.results' в' [] ', когда' search' пуст? Попытка сделать это, как показано в моем коде, приводит к возврату последнего вызова AJAX после того, как результаты были очищены. –

+0

Установите флаг, чтобы при разрешении обещания он знал, что он должен игнорировать результаты. Другой вариант - очистить тайм-аут, но это бесполезно. –

Смежные вопросы