使用React,Redux和Redux-saga构建媒体库-第1部分

Building applications with React can be overwhelming even after you’ve understood the elegant philosophy behind it. More so, managing large applications with React can be confusing at first. The ecosystem has grown with great libraries to save you some nightmare. But that also makes it difficult at first to figure out which library to use.

即使您已经了解了它背后的优雅理念,使用React构建应用程序也可能会让人不知所措。 更重要的是,起初使用React管理大型应用程序可能会造成混乱。 生态系统已经有了庞大的图书馆,可以为您节省一些噩梦。 但这也使得一开始很难确定要使用哪个库。

In this two-part tutorial, we’ll build and deploy a media library app. The application allows users to search and display images and short videos from external services (Flickr and Shutterstock). It would also allow users to select images and videos for preview.

在这个分为两部分的教程中,我们将构建和部署媒体库应用程序。 该应用程序允许用户搜索和显示来自外部服务(Flickr和Shutterstock)的图像和短视频。 它还将允许用户选择图像和视频进行预览。

We will build this application with:

我们将使用以下命令构建该应用程序:

We will be using Yahoo’s Flickr API and ShutterStock API for images and short videos respectively.

我们将分别使用Yahoo的Flickr APIShutterStock API来处理图像和短视频。

This tutorial assumes you have a basic understanding of Javascript and React. Don't worry if you have none. We will walk through and build the application from the ground up.

本教程假定您对Javascript和React有基本的了解。 如果没有,请不要担心。 我们将逐步进行并从头开始构建应用程序。

我们将建立什么 ( What We'll Build )

Part 1 of this tutorial would cover basic React setup with create-react-app package, organizing our project workflow, defining routes, and of course testing it out.

本教程的第1部分将介绍使用create-react-app package基本的React设置,组织我们的项目工作流程,定义路线并进行测试。

In Part 2, we will be using Redux and its async libraries; we will set it up and then integrate it into our application. Finally, we will deploy our application to Heroku for sharing with our friends. Our application would look thus when we're done.

在第2部分中,我们将使用Redux及其异步库。 我们将对其进行设置,然后将其集成到我们的应用程序中。 最后,我们将应用程序部署到Heroku以便与朋友共享。 完成后,我们的应用程序将显示出来。

Our app will be structured to allow you to either contribute to it or use as sample boilerplate for bootstrapping your React/Redux applications.

我们的应用程序的结构将使您可以为它做出贡献,或者用作自举React / Redux应用程序的示例样板。

Great philosophy for learning:

伟大的学习哲学:

Imitate, assimilate, and innovate - *Clark Terry.***

模仿,吸收和创新-* Clark Terry。***

项目设置 ( Project Setup )

There are loads of React boilerplate out there to help you get started with React. But we’ll be using create-react-app authored by the Facebook team. It allows you create React applications with no configuration. create-react-app provides developers with the benefits of more complex setup out of the box.

有大量的React样板可以帮助您开始使用React。 但是,我们将使用Facebook团队创作的create-react-app 。 它允许您创建没有配置的React应用程序。 create-react-app可为开发人员提供开箱即用的更复杂设置的好处。

Let’s get started…

让我们开始吧…

$npm install -g create-react-app   # First, install the package globally
$ create-react-app media-library   # Create media-library application

Bam. Our React basic setup is complete with scripts to start, build, and eject. Take a look at your** package.json.**

am 我们的React基本设置包含用于启动构建弹出的脚本的完整信息。 看看你的** package.json。**

Let’s test it out.

让我们测试一下。

$cd media-library && npm start

Now, we can structure our project directory and add other dependencies.

现在,我们可以构建项目目录并添加其他依赖项。

$npm install --save redux redux-saga react-router@2.4 react-redux  # Install dependencies
$ rm -rf src/**  # To clean the default sample app

项目目录 (Project Directory)

Media-library
    - public
        - favicon.ico
        - index.html
    - src
        - Api
            - api.js
        - actions
            - mediaActions.js
        - common
            - Header.js
        - components
            - HomePage.js
            - PhotoPage.js
            - VideoPage.js
        - constants
            - actionTypes.js
        - containers
            - App.js
            - MediaGalleryPage.js
        - reducers
            - imageReducer.js
            - index.js
            - initialState.js
            - videoReducer.js
        - sagas
            - mediaSaga.js
            - index.js
            - watcher.js
        - styles
            - style.css
        - store
            - configureStore.js
        - routes.js
        - index.js
    - package.json

If the project directory looks verbose, just be patient and let's walk-through. The intent of the project structure is to allow you extend the application’s functionality beyond this tutorial. This would help you stay organized moving forward.

如果项目目录看起来很冗长,请耐心等待,然后逐步进行介绍。 项目结构的目的是允许您将应用程序的功能扩展到本教程之外。 这将帮助您保持有条理的前进。

If you’re new to Redux, I recommend* Lin Clark’s** article on *A Cartoon Intro To Redux.

如果您不熟悉Redux,我建议* Lin Clark的**关于Redux的卡通简介的文章

What the heck is happening up there?

那到底发生了什么事?

  1. View layer is our React component. It makes a request for action based on interactions on/with the application.

    视图层是我们的React组件。 它基于与应用程序之间的交互来请求采取措施。
  2. Action, commonly called action creator returns a formatted object of the action type and optional payload which is then dispatched to the store.

    Action (通常称为操作创建者)返回操作类型的格式化对象和可选的有效负载,然后将其分派到商店。
  3. Redux-saga is a Redux middleware for handling async operations like fetching photos and videos from our API. It makes asynchronous operations look like standard Javascript synchronous code making it easy to read, test, and reason.

    Redux-saga是Redux中间件,用于处理异步操作,例如从我们的API中获取照片和视频。 它使异步操作看起来像标准Java同步代码,从而易于阅读,测试和推理。
  4. APIs are resource locations to fetch photos and videos in our own case.

    API是我们自己获取照片和视频的资源位置。
  5. Reducers are simply pure functions whose purpose in life is to accept the state tree and an action from the store; make a copy of the previous state, transform it and then return a new state to the store.

    简器是纯粹的函数,其生活的目的是接受状态树和来自存储的动作。 复制以前的状态,进行转换,然后将新状态返回到商店。
  6. Store is a single object that holds the complete state of your application. It delegates the reducer with the responsibility of changing state when an action is dispatched.

    Store是保存应用程序完整状态的单个对象。 派遣动作时,它负责将减速器委派给更改状态的责任。

When the store receives an updated state, it transmits to the view layer to be rerendered.

当商店收到更新状态时,它将传输到视图层以进行重新呈现。

Now that we understand the workflow, let’s dive into coding.

现在我们了解了工作流程,让我们开始进行编码。

common/Header.js

common / Header.js

import React from 'react';
import { Link, IndexLink } from 'react-router';

const Header = () => (
  <div className="text-center">
    <nav className="navbar navbar-default">
      <IndexLink to="/" activeClassName="active">Home</IndexLink>
      {" | "}
      <Link to="library" activeClassName="active">Library</Link>
    </nav>
  </div>
);

export default Header;

Link allows you navigate to different routes in your application.

链接可让您导航到应用程序中的其他路线。

IndexLink is the same as Link with the exception of OnlyActiveOnIndex prop set on it.

IndexLink与Link相同, 只是在其上设置了OnlyActiveOnIndex属性

components/HomePage.js

组件/HomePage.js

import React from 'react';
import { Link } from 'react-router';

// Home page component. This serves as the welcome page with link to the library
const HomePage = () => (
  <div className="jumbotron center">
    <h1 className="lead">Welcome to Media Library built with React, Redux, and Redux-saga </h1>
    <div>
      <Link to="library">
        <button className="btn btn-lg btn-primary"> Visit Library</button>
      </Link>
    </div>
  </div>
);

export default HomePage;

containers/App.js

容器/App.js

import React, { Component, PropTypes } from 'react';
import Header from '../common/Header';

// The parent component renders the Header component and component(s) in the
// route the user navigates to.
class App extends Component {
  render() {
    return (
      <div className="container-fluid text-center">
        <Header />
        {this.props.children}
      </div>
    );
  }
}
App.propTypes = {
  children: PropTypes.object.isRequired
};

export default App;

App component is the parent component of our app. Every other component is a child to it. this.props.children is where other child components are rendered.

应用程序组件是我们应用程序的父组件。 其他所有组件都是该组件的子代。 this.props.children是其他子组件的渲染位置。

We will implement the library route and the component that maps to it in Part 2 of this tutorial.

在本教程的第2部分中,我们将实现路由和与其映射的组件。

You would notice that for Header and HomePage components, we’re using stateless functional component. This approach allows us to separate our presentational components from the container components.

您会注意到,对于HeaderHomePage组件,我们使用的是无状态功能组件 。 这种方法使我们能够将表示性组件与容器性组件分开。

It’s a good practice as it enforces functional composition and component’s reusability. Whereas container components are responsible for your business logic and connecting with the store, presentational components are responsible for the look of your view.

这是一个好习惯,因为它可以增强功能组合和组件的可重用性。 容器组件负责您的业务逻辑并与商店连接,而演示组件负责您的视图外观。

Simply put, presentational components are components whose purpose in life is to render values to the DOM. Container components also known as smart components provide props and behavior to presentational components.

简而言之,表示性组件是其目的是将值呈现给DOM的组件。 容器组件也称为智能组件,可为演示组件提供道具和行为。

Let’s wire up our project routes.

让我们整理一下项目路线。

routes.js

routes.js

import React from 'react'; 
import { Route, IndexRoute } from 'react-router';
import App from './containers/App';
import HomePage from './components/HomePage';

// Map components to different routes.
// The parent component wraps other components and thus serves as  the entrance to 
// other React components.
// IndexRoute maps HomePage component to the default route
export default (
  <Route path="/" component={App}> 
    <IndexRoute component={HomePage} />
  </Route>
);

Now let's add the entrance to our application - index.js.

现在,将入口添加到应用程序index.js中

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, browserHistory } from 'react-router';
import routes from './routes';

// We require the routes and render to the DOM using ReactDOM API
ReactDOM.render(
    <Router history={browserHistory} routes={routes} />, 
    document.getElementById('root')
);

We pass in our routes and *browserHistory* as props to Router here. browserHistory uses your browser’s History API to create a clean and real URL without the gibberish that comes with using hashHistory. *hashHistory* has its use case, though.

我们在此处传递路线和* browserHistory *作为对Router的支持 。 browserHistory使用您的浏览器的History API创建一个干净而真实的URL,而不会使用hashHistory带来​​乱码。 * hashHistory *有其用例。

Router is a high-level API that keeps your UI and URL in sync. It ensures that required props are passed whenever you change URL.

路由器是高级API,可让您的UI和URL保持同步。 它确保您更改URL时都会传递必需的道具。

ReactDOM is the API for mounting our application on the DOM node(root, in our own case).

ReactDOM是用于将我们的应用程序安装在DOM节点上的API( 在我们自己的情况下为 root )。

Two more things before we test our app.

在测试我们的应用程序之前,还有两件事。

Add a bootstrap link to a CDN in our public/index.html.

在我们的public / index.html中将引导链接添加到CDN

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

Let’s add some custom styling.

让我们添加一些自定义样式。

styles/style.css

styles / style.css

body {
  margin: 0;
  padding: 0;
  font-family: Helvetica, Arial, Sans-Serif, sans-serif;
  background: white;
}

.title {
  padding: 2px;
  text-overflow-ellipsis: overflow;
  overflow: hidden;
  display: block;
}

.selected-image, .select-video {
  height: 500px;
}

.selected-image img, .select-video video {
  width: 100%;
  height: 450px;
}

.image-thumbnail, .video-thumbnail {
  display: flex;
  justify-content: space-around;
  overflow: auto;
  overflow-y: hidden;
}

.image-thumbnail img, .video-thumbnail video {
  width: 70px;
  height: 70px;
  padding: 1px;
  border: 1px solid grey;
}

Let’s test our app now…

让我们现在测试我们的应用程序…

$npm start

Navigate to http://localhost:3000 on your browser.

在浏览器上导航到http:// localhost:3000

Bam!!! We’re up again

am! 我们又起来了

结语 ( Wrap up )

Building application with ReactJs gets better as you understand the flow. In this part, we did:

当您了解流程时,使用ReactJs构建应用程序会变得更好。 在这一部分中,我们做了:

  1. Set up configurations.

    设置配置。
  2. Set up project structure.

    设置项目结构。
  3. Complete Header, Homepage, and App(parent) components.

    完整的标题,主页和应用程序(父)组件。
  4. Map routes to different components.

    将路线映射到不同的组件。
  5. What else? We tested our app.

    还有什么? 我们测试了我们的应用程序。

In the second part of this tutorial, we will be exploring the power of Redux, Redux-saga and separating our state management system from the React components for scalability and maintainability.

在本教程的第二部分中,我们将探索Redux,Redux-saga的功能,并将状态管理系统与React组件分开,以实现可伸缩性和可维护性。

翻译自: https://scotch.io/tutorials/build-a-media-library-with-react-redux-and-redux-saga-part-1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值