スクラッチは、戦闘の反応:ブックマーク-1構築するためのクラウド環境を反応させます

概要章:戦闘クラウドのブックマークをREACT

Benpianは、主に、開発環境を構築するために反応し、最初の本当のシリーズであるcreate-react-appに基づいて、以下の機能を加えました。

  • ご紹介するのに必要なantdコンポーネントライブラリ、サポートカスタムテーマ
  • 以下の文法をサポートし、CSS-モジュールを使用
  • 設定ルーティング
  • サポートhttpリクエスト
  • 設定再来

:8.0よりも大きいノードのバージョンが必要です。

作成反応するアプリを作成します。

  1. インストール
npm install -g create-react-app
  1. 作成は、アプリケーションの反応します
create-react-app bookmark-world

以下に示すようなディレクトリ構造を生成:

ディレクトリ構造

設定antd、以下

その設定を編集する方法は2つあります。

  • することでnpm run eject、設定ファイルを暴露し、構成ファイルを変更し、以下の方法がエレガントに比べてではないため、考えられません。
  • することでreact-app-rewired設定をカバーしています。

カバレッジ構成 - 後続の構成の変更が第二で必要とされます。

最初の依存関係をインストール

必要と反応-APP-再配線の2.1.Xバージョンでcustomize-cra覆うように構成することができます。次の依存関係をインストールする必要があります。

  • 反応-APP-再配線、カバーに配置されました
  • カスタマイズ-CRAを覆うように配置
  • antd、UIライブラリー
  • バベル - プラグインのインポート、需要紹介antd
  • 以下、それほどのサポート
  • あまりローダー、以下のサポート

コードは以下の通りであります:

npm install --save react-app-rewired customize-cra antd babel-plugin-import less less-loader

package.jsonを変更

react-app-rewired元の代替アウトreact-scripts

/* package.json */
"scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test",
+   "test": "react-app-rewired test",
}

コンフィグ-overrides.jsを作成します。

あるプロジェクトのルートディレクトリでは、package.json同じディレクトリに作成するconfig-overrides.jsファイルを次のように:

const { override, fixBabelImports, addLessLoader } = require("customize-cra");

module.exports = override(
  fixBabelImports("import", {
    libraryName: "antd",
    libraryDirectory: "es",
    style: true
  }),
  addLessLoader({
    localIdentName: "[local]--[hash:base64:5]",
    javascriptEnabled: true,
    modifyVars: { "@primary-color": "#1DA57A" }
  })
);

CSSモジュールを使用します

CSS-モジュールを使用するには、ファイル名をCSSに必要fileName.module.less、その後、次のように、アセンブリの通常の使用で導入することができます。

デフォルトのファイルケースは、CSSモジュールの文言を使用する.module.lessでなければならないことに注意してください

import React, { Component } from "react";
import { Button } from "antd";
import styles1 from "./index.module.less";

class Hello extends Component {
  render() {
    return (
      <div className={styles1.main}>
        hello
        <div className={styles1.text}>world</div>
        <Button type="primary">你好</Button>
        <div className="text1">heihei</div>
      </div>
    );
  }
}

export default Hello;

設定ルーティング

まず、srcディレクトリ構造を変更します。次のように変更:

ディレクトリ構造

カタログは説明しました:

  • 資産:ストレージアイコン、小さな絵や他のリソースファイル
  • コンポーネント:共通部品の保管
  • レイアウト:入れ子ルーティングコードの再利用中性紫用パターン記憶コンポーネント
  • ページ:ストアページコンポーネント
  • Reduxの:Reduxの関連ストレージ
    • アクション:店舗アクション
    • 減速:減速のストレージ操作
  • utilの:ツール

削除しserviceWorker.jsたファイルを、およびindex.jsそれに関連するコードを削除します。これは、使用してオフラインに関係しています。

その後、インストールreact-routerによって異なります。

cnpm install --save react-router-dom

ルートの最初からすべてを反応させるJSの本質を理解することができるようになります、反応-ルータ-DOMをルート操作にいくつかのルーティングコンポーネントを提供します。このプログラムは、使用するhistoryルーティングを。

まず、変更index.js置かルートコンポーネント<BrowserRouter>経路履歴を開くことが次を。コードは以下の通りであります:

// index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { BrowserRouter } from "react-router-dom";

const s = (
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

ReactDOM.render(s, document.getElementById("root"));

そして、ルートを設定するには、多くの方法がここに道アドホックルーティングコード、およびルーティングの設定意志App.jsxセンターによって、があります。(また、コンフィギュレーションファイルに基づいて、その後、コード構成ファイルの解析を書き込みます)

次のようにホームとルーティングに参加するためにログインし、メインのコードは次のようになります。


render() {
  const mainStyle = {
    fontSize: "0.16rem"
  };
  return (
    <Provider store={store}>
      <div className="fullScreen" style={mainStyle}>
        <Switch>
          <Route exact path="/" component={Main} />
          <Route exact path="/public/login" component={Login} />
          <Route exact path="/404" component={NotFound} />
          {/* 当前面的路由都匹配不到时就会重定向到/404 */}
          <Redirect path="/" to="/404" />
        </Switch>
      </div>
    </Provider>
  );
}

用語集:

  • スイッチ:このコンポーネントは、一つだけのマッチを表し、試合はダウン一致し続けていません
  • ルート:ルーティングコンポーネント
  • 正確:これがオンになっている場合、正確な一致を示し、/唯一の一致/、そうでなければ、すべてのパスが一致
  • リダイレクト:(そこには開いていないので、リダイレクト構成要素が現在の面はこれを一致する一致しないexactとパスである/)にリダイレクトし、その後、/404

これは、関連するその後の使用のネストされたルートをルーティングするより詳細な説明であろう。

httpリクエストツールを構成します

HTTPリクエストツールの選択はここにありますaxios

最初のインストールが異なります。

cnpm install --save axios

然后编写工具类util/httpUtil.js,代码如下:

// httpUtil.js

import { notification } from "antd";
import axios from "axios";

//定义http实例
const instance = axios.create({
  //   baseURL: "http://ali.tapme.top:8081/mock/16/chat/api/",
  headers: {
    token: window.token
  }
});

//实例添加拦截器
instance.interceptors.response.use(
  function(res) {
    return res.data;
  },
  function(error) {
    console.log(error);
    let message, description;
    if (error.response === undefined) {
      message = "出问题啦";
      description = "你的网络有问题";
    } else {
      message = "出问题啦:" + error.response.status;
      description = JSON.stringify(error.response.data);
      //401跳转到登录页面
    }
    notification.open({
      message,
      description,
      duration: 2
    });
    setTimeout(() => {
      if (error.response && error.response.status === 401) {
        let redirect = encodeURIComponent(window.location.pathname + window.location.search);
        window.location.replace("/public/login?redirect=" + redirect);
      }
    }, 1000);
    return Promise.reject(error);
  }
);

export default instance;

主要实现了如下功能:

  • 自动添加 token,设计前后端通过 jwt 做认证,因此每个请求都要加上 token
  • 响应预处理,如果有错误,自动弹窗提示。如果响应码为 401,重定向到登录页面。

配置 redux

redux 算是 react 的一大难点。这里我们可以把 redux 理解成一个内存数据库,用一个对象来存储所有的数据.

对这个数据的修改有着严格的限制,必须通过 reducer 来修改数据,通过 action 定义修改的动作。

这里以用户登录数据为例。

定义

  1. 首先定义 action,创建文件redux/action/loginInfoAction.js,代码如下:
// 定义登录信息在store中的名字
export const DATA_NAME = "loginInfo";

//定义修改loginInfo type
export const CHANGE_LOGIN_INFO = "changeLoginStatus";

export const changeLoginInfo = (token, userInfo) => {
  return {
    type: CHANGE_LOGIN_INFO,
    data: {
      token,
      userInfo
    }
  };
};
  • CHANGE_LOGIN_INFO :定义操作类别
  • changeLoginInfo: 定义一个 action,在组件中调用,传入要修改的数据,在这里加上 type 上传递到 reducer 中处理.
  1. 定义 reducer,创建文件redux/reducer/loginInfo.js,代码如下:
import * as loginAction from "../action/loginInfoAction";

function getInitData() {
  let token, userInfo;
  try {
    token = localStorage.getItem("token");
    userInfo = JSON.parse(localStorage.getItem("userInfo"));
  } catch (e) {
    console.error(e);
    token = null;
    userInfo = null;
  }
  window.token = token;
  window.userInfo = userInfo;
  return {
    token,
    userInfo
  };
}

const LoginStatusReducer = (state = getInitData(), action) => {
  switch (action.type) {
    case loginAction.CHANGE_LOGIN_INFO:
      return { ...action.data };
    default:
      return state;
  }
};

export default LoginStatusReducer;
  • getInitData 方法用于初始化 userInfo 数据,这里写的比较复杂,会先从 localeStore 中取数据,然后挂载到 window 中,方便httpUtil中获取 token。
  • LoginStatusReducer 方法用于处理 action 中的数据,输出处理后的 loginInfo 数据。
  1. 编写 reducer 汇总类(redux/reducer/index.js),所有 reducer 都要汇总到一个方法中,这样就能生成整个系统的 store 对象。代码如下:
import { combineReducers } from "redux";
import { DATA_NAME } from "../action/loginInfoAction";
import loginInfo from "./loginInfo";

const data = {};
data[DATA_NAME] = loginInfo;

const reducer = combineReducers(data);

export default reducer;
  1. 编写redux/index.js,这里生成真正的数据对象,代码如下:
import { createStore } from "redux";
import reducer from "./reducer";

const store = createStore(reducer);

export default store;
  1. 最后将 store 绑定到根节点(App.js)中即可,修改部分如下:

使用

这里以登录页为例,学习如何获取到 loginInfo 和修改 loginInfo.

  1. ログインページを作成するためのコンポーネントは、pages/public/Login/index.js
    次のようにページのコードはログイン:
import React, { Component } from "react";
import queryString from "query-string";
import { Button, Input, message } from "antd";
import IconFont from "../../../components/IconFont";
import styles from "./index.module.less";
import { connect } from "react-redux";
import { changeLoginInfo, DATA_NAME } from "../../../redux/action/loginInfoAction";
import axios from "../../../util/httpUtil";

function mapStateToProps(state) {
  return state[DATA_NAME];
}

function mapDispatchToProps(dispatch) {
  return {
    updateLoginInfo: (token, userInfo) => dispatch(changeLoginInfo(token, userInfo))
  };
}

class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      username: "",
      password: ""
    };
    this.query = queryString.parse(window.location.search);
  }

  usernameInput = e => {
    this.setState({ username: e.target.value });
  };
  passwordInput = e => {
    this.setState({ password: e.target.value });
  };

  submit = () => {
    axios.post("/public/login", this.state).then(res => {
      localStorage.setItem("token", res.token);
      localStorage.setItem("userInfo", JSON.stringify(res.userInfo));
      window.token = res.token;
      window.userInfo = res.userInfo;
      message.success("登录成功");
      this.props.updateLoginInfo(res.token, res.userInfo);
      if (this.query.redirect) {
        this.props.history.replace(decodeURIComponent(this.query.redirect));
      } else {
        this.props.history.replace("/");
      }
    });
  };

  render() {
    return (
      <div className="fullScreen flex main-center across-center">
        // 省略其他部分
        <Button type="primary" onClick={this.submit}>
          登录
        </Button>
        ...
      </div>
    );
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Login);

最も重要なの一つは、次の3つの部分であります:

  • mapStateToProps:このメソッドは、全体ストアからデータを取得する必要があり、組み立てログイン小道具に配信。
  • mapDispatchToProps:このメソッドは、データストアを変更するために使用され、関数はまた、アセンブリログイン小道具にバインドされたオブジェクトを返す、changeLoginInfo返さアクションに従って、減速中に関数呼び出しを処理するためのパラメータをdispath。
  • 上記方法は、小道具を得ることができるように、ログインおよび機能結合する2つのコンポーネントを接続するために使用されます。withRouterがある場合は、最も外側の層の上にwithRouter必要があります。

インターフェイスのログインアクセスが現在モックデータをYAPIされ、実際の背景コードは、後に書き込まれます。

エンディング

ルーキーとしてだけで、反応するあなたを歓迎するために、ダニエルの批判を学習し始めて。

出典:GitHubには、タグに切り替える:第一篇:环境搭建、我々はBenpianソースのとしてそれを見ることができます。

:に掲載された記事www.tapme.top/blog/detail/20190626

おすすめ

転載: www.cnblogs.com/wuyoucao/p/11273965.html