【问题标题】:Learning to use React but I'm stumped on how to incorporate promises学习使用 React 但我对如何合并 Promise 感到困惑
【发布时间】:2018-04-09 05:27:37
【问题描述】:

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

在我的 index.js 文件中,我定义了一个 App 类,它的构造函数调用 API 以获取与默认搜索词“国家地理”匹配的视频列表。一旦这些结果回来(需要在这里使用一个承诺),我想调用 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'));

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

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

【问题讨论】:

    标签: jquery reactjs redux promise


    【解决方案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

    【讨论】:

      【解决方案2】:

      我建议使用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 请求库(request-promise、fetch),发出内联 http 请求(并绕过 redux 流程),它也可以正常工作,但我认为它会在您的情况下(使用状态容器时)这样做会更混乱,更不干净。利用redux流程,让http请求通过redux循环:dispatch action(例如http请求)-> change state in reducer(请求后成功或失败)-> 更新用户界面

      希望对您有所帮助。

      【讨论】:

        【解决方案3】:

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

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

        我建议不要仅将 jQuery 包含在内,因为它具有承诺功能,因为它会占用您的用户大量不必要的带宽,而库的其余部分未被使用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-20
          • 1970-01-01
          • 2019-10-29
          • 1970-01-01
          • 2020-02-19
          • 1970-01-01
          相关资源
          最近更新 更多