学习使用React,但我对如何融入承诺感到困惑

时间:2018-04-08 20:30:37

标签: jquery reactjs redux promise

我理解promises是如何工作的,并且过去曾使用过JQuery做出承诺。我正在构建一个非常简单的应用程序,它使用YouTube API来显示视频。我碰到了一堵砖墙,因为我遇到了一种情况,我需要使用一个承诺,但不知道如何。

在我的index.js文件中,我定义了一个App类,其构造函数调用API以获取与默认搜索词“national geographic”匹配的视频列表。一旦这些结果回来(需要在这里使用一个承诺),我想调用this.setSelectedVideo来获取要播放的特定视频。

//  Node Modules
import React        from 'react';
import ReactDOM     from 'react-dom';
import YTSearch     from 'youtube-api-search';

//  Components
import SearchBar    from './components/search_bar';
import VideoList    from './components/video_list';
import VideoDetail  from './components/video_detail';

const API_KEY_YOUTUBE = <MY_YOUTUBE_API_KEY>;

class App extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            videos: [],
            selectedVideo: null
        };

        //  initialize videos: finish this up when you learn how to do redux promises
        this.videoSearch('National Geographic');
        this.setSelectedVideo(this.state.videos[0]);
    }

    videoSearch(term) {
        //  Make AJAX request to YouTube for a list of videos matching term.
        YTSearch({ key: API_KEY_YOUTUBE, term: term }, videos => {
            this.setState({ videos: videos });
        });
    }

    setSelectedVideo(video) {
        //  Make AJAX request to YouTube for the specific video being played.
        console.log(video);
    }

    render() {
        return (
            <div>
                <div className="row margin-bottom-md">
                    <div className="col-12 col-lg-8">
                        <SearchBar onSearchTrigger={ term => this.videoSearch(term) } />
                    </div>
                </div>
                <div className="row margin-bottom-md">
                    <div className="col-12 col-lg-8">
                        <VideoDetail video={ this.state.selectedVideo } />
                    </div>
                    <div className="col-12 col-lg-4">
                        <VideoList 
                            videos={ this.state.videos }
                            onVideoSelect={ selectedVideo => this.setSelectedVideo({ selectedVideo }) }
                            selectedVideo={ this.state.selectedVideo }
                        />
                    </div>
                </div>
            </div>
        );
    }

}   //  App class end

//  Take this component's generated HTML and put it on the page.
ReactDOM.render(<App />, document.querySelector('#react-render'));

我一直在网上四处寻找并听过一些选择。 我可以使用香草JS承诺。 2.我可以以某种方式将JQuery合并到我的应用程序中并使用其promise函数。不幸的是,我需要从NPM中包含一个单独的包管理器来执行此操作? 我听说redux有承诺功能。

这三个选项中哪一个最好/我在这里实施简单承诺的最简单方法是什么?

3 个答案:

答案 0 :(得分:1)

未经测试,但这应该符合您的要求:

videoSearch(term) {
    //  Make AJAX request to YouTube for a list of videos matching term.
    YTSearch({ key: API_KEY_YOUTUBE, term: term }, videos => {
        this.setState({ 
            videos: videos,
            selectedVideo: videos[0]
        });
    });
}

来源:https://medium.com/@charlie.spencer/making-requests-to-the-youtube-api-with-react-fbd50fa8d77e

答案 1 :(得分:1)

我建议使用redux-api-middleware。 由于您使用状态容器(redux)管理应用程序,因此使用redux类型的流样式生成http请求是一个好习惯:调度操作将依次进行实际的http调用,然后相应地调用预定义的reducer 。

所以它看起来像这样:

// actions_file.js

import { RSAA } from `redux-api-middleware`;

// the action itself
export function myYoutubeAction(someArg) {
  return {
      [RSAA]: {
        endpoint: '<YOUTUBE_API_PATH>',
        method: 'GET',
        types: ['REQUEST_REDUCER', 'SUCCESS_REDUCER', 'FAILURE_REDUCER']
      }
}

// reducer_file.js

  // this reducers is called right after http request made
  'REQUEST_REDUCER': (state, action) {
    const { response } = action.payload;
    ...
    ...
    // DO SOME STUFF AND UPDATE STATE..
  }

  // this reducers is called right after http request is back
  'SUCCESS_REDUCER': (state, action) {
    const { response } = action.payload;
    ...
    ...
    // DO SOME STUFF WITH RESPONSE AND UPDATE STATE..
  }

当然你可以使用本机(或外部)http请求库(请求 - 承诺,获取),发出内联http请求(并绕过redux流),它也可以正常工作,但我认为它会在你的情况下(使用状态容器时)这样做会更麻烦,更不干净。利用redux流量并让http请求通过redux圈:调度操作(例如,http请求) - &gt; reducer中的改变状态(在请求,成功或失败之后) - &gt; 更新用户界面

希望它有所帮助。

答案 2 :(得分:0)

我真的取决于你的情况,但由于近10% of all current users不使用支持本机Promise(IE)的浏览器,我建议使用外部库。

我已经使用Bluebird很长一段时间了,我会推荐它,但有很多替代品可供选择。

我建议不要仅仅因为它的承诺功能而包含jQuery,因为它会为你的用户带来大量不必要的带宽,而其余的库却未被使用。