使用React Hooks 16版本开发项目

前言: 本文仅展示部分基础代码,不涉及原理。

一、 基本目录树

□ public (公共资源文件)
□ nav
□ sprite
- index.html
□ src (源代码)
□ common (公共模块)
□ components (组件/页面)
□ routes (路由文件)
□ style (样式)
□ utils (公共方法)
- App.js
- App.scss
- index.js (入口文件)

  • package.json
  • README.md

二、 入口文件示例

1. index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(, document.getElementById('pageWrapper'));

2. App.js

import React from 'react';
import './App.scss';
import { BrowserRouter } from 'react-router-dom';
import { Home } from './routes/Home';

function App() {
    return (
        
            
        
    );
}

export default App;

三、 路由文件示例

1. routes/Home.js

// 用户登录后的主界面入口模块,界面结构为:左侧菜单栏+顶部导航条+内容区域
function AppContainer() {
  // 通常使用现有的UI组件 配合 组件
  // 例
    return (
    
      
      
menuName ... ... ...
); } export default function Home() { return ( ); }

2. 路由对应的 组件/页面

  • components/Example/Index.js
import React from 'react';

export default function Example() {
    return (
        
我是组件内容
) };

四、 axios请求示例

1. lib/axios.js 封装axios方法

import Axios from 'axios';
import { request } from './request';

// axios 中间件注册  文档:https://github.com/axios/axios
const axiosInstance = Axios.create();

// 请求拦截示例
axiosInstance.interceptors.request.use(
    (config) => {
        let { url, data } = config;
        const headers = Object.assign({}, config.headers);
        // 统一请求网关接口
        url = "/gateway";
        // 请求头添加公共参数
        Object.assign(headers, {
        "X-Common-Action": ActionName,
        "X-Common-Service": ServiceName,
        ... ...
        });
        data = JSON.stringify(data);

        Object.assign(config, {
          url,
          headers,
        });
        return config;
    }, function (error) {
        return Promise.reject(error)
    }
)

// 响应拦截示例
axiosInstance.interceptors.response.use(
    res => {
        const { status, data } = res;
        
        if (status === 401) {
            window.location.href = '/login';
        }
        return res;
    }, error => {
        return Promise.reject(error);
    }
);

// 请求体添加公共参数
const mergeParams = (params) => {
  const commonParams = {
    Version: params.Version,
    Action: params.url,
    Service: params.name,
  };
  const proxyObj = {
    ...params.data,
  };
  return Object.assign(commonParams, proxyObj);
};

const axios = (config, params) => {
    const requestConfig = request(config);
    const { method, url, version } = requestConfig;
    return axios[method](url, mergeParams({ data: params, ...config }), {
      Version: version,
    });
};

// get请求 参数格式转换 (转换为 ?key=value&key=value 字符串)
function UrlDataFormat(param) {
  const keys = Object.keys(param);
  let requestBody = "";
  let requestobj = "";
  let requestend = "";
  let lastrequest = "";
  for (let i = 0; i < keys.length; i++) {
    if (typeof param[keys[i]] === "object") {
      const dd = param[keys[i]];
      const keyitems = Object.keys(dd);
      for (let k = 0; k < keyitems.length; k++) {
        if (typeof dd[keyitems[k]] === "object") {
          const keyon = Object.keys(dd[keyitems[k]]);
          for (let j = 0; j < keyon.length; j++) {
            if (typeof dd[keyitems[k]][keyon[j]] === "object") {
              const lastone = Object.keys(dd[keyitems[k]][keyon[j]]);
              for (let f = 0; f < lastone.length; f++) {
                lastrequest += `${keys[i]}.${keyitems[k]}.${keyon[j]}.${f}=${
                  dd[keyitems[k]][keyon[j]][f]
                }&`;
              }
            } else {
              requestend += `${keys[i]}.${keyitems[k]}.${keyon[j]}=${
                dd[keyitems[k]][keyon[j]]
              }&`;
            }
          }
        } else {
          requestobj += `${keys[i]}.${keyitems[k]}=${dd[keyitems[k]]}&`;
        }
      }
    } else {
      requestBody += `${keys[i]}=${param[keys[i]]}&`;
    }
  }
  return `?${requestBody}${requestobj}${requestend}${lastrequest}`;
}

axios.get = (url, params, config) =>
  axiosInstance({
    method: "get",
    url:
      url +
      UrlDataFormat({
        ...params,
      }),
    ...config,
  })
    .then((res) => {
      return Promise.resolve(res.data.Response);
    })
    .catch((err) => {
      return Promise.reject(err);
    });

axios.post = (url, params, config) => {
  return axiosInstance({
    method: "post",
    url,
    data: {
      ...params,
    },
    ...config,
  })
    .then((res) => {
      return Promise.resolve(res.data.Response);
    })
    .catch((err) => {
      return Promise.reject(err);
    });
};

export default axios;

2. lib/request.js (在axios.js文件里有调用request方法)

import apiName from './apiName';

export function request(serviceName) {
    const config = apiName[serviceName];
    return {
        url: `/${config.url}`,
        method: config.method,
        version: config.version,
    }
}

3. lib/apiName.js 配置接口列表

export default {
  Login: {
    method: "post",
    url: "/Login",
    version: "0.0.1",
  },
  ...
}

4. store/appApi.js 导出接口调用方法

import axios from "../lib/axios";

export function doLogin(data) {
  return axios({ name: "ServerName", url: "Login" }, data)
    .then((res) => Promise.resolve(res))
    .catch((err) => Promise.reject(err));
}

5. src/Login/Login.js 发起请求

import { doLogin } from '../../store/appApi';

doLogin(data).then(result => {
    if (!result.Response.Error) {
        history.push('/home'); // 登录成功,跳转到主界面
    }
})

五、 context状态管理

1. context/appContext.js 定义context

import React from "react";

export const AppContext = React.createContext({
  LoginInfo: {},
  setLoginInfo: () => {},
});

2. src/Login/Login.js 使用

import React, { useContext } from "react";
import { AppContext } from "../../context/appContext";

const appContext = useContext(AppContext);

// 更新context状态
appContext.setLoginInfo(Result);

// 获取context状态
console.log(appContext.LoginInfo);

六、 props 父子组件数据传递

1. parent.js 父组件

import React, { useState } from 'react';
import Child from './child';  // 引入子组件

function Parent(){
    const [state, setState] = useState(0);  // 定义要传递的数据
    
    // 定义要传递的方法
    function parentFn(){
        // 做某事...
    }

    return (
        
        
    );
}

2. child.js 子组件

import React, { useEffect } from 'react';

function Child(props){
    
    useEffect(() => {
        console.log(props.state);  // 访问父组件的state

        props.setState(1); // 修改父组件的state
    }, []);

    return (
        
    );
}

七、 常用 Hooks 新特性

1. useState

import React, { useState } from 'react';

function Example() {
    // ① 定义
    const [useName, setUseName] = useState("");
    const [age, setAge] = useState(0);
    const [list, setList] = useState([]);

    // ② 修改
    setUseName("小明");
    setAge(18);
    setList(['吃饭','睡觉']);

    return (
      

姓名: {useName}

年龄: {age}

爱好:

{list.map((item, index) => { return (

{item}

); })}
); }

2. useEffect

import React, { useEffect } from "react";

function Example() {
    const [data, setData] = useState([]);
    const [params, setParams] = useState({});

    useEffect(() => {
        setData([]);
    }, []); // 参数[] 第一次渲染后,仅调用一次。常用于动态请求数据渲染页面。

    useEffect(() => {
        setData([]);
    }, [params]); // params参数每次改变时都触发调用。
}

3. useRef

import React, { useRef } from 'react';

function Example() {
    const divEle = useRef(null);  // 定义

    useEffect(() => {
        console.log(divEle.current);  // 访问
    }, []);

    return (
        
); }

4. useRouter

① 页面跳转

import React from 'react';
import useRouter from 'use-react-router';

function Example() {
    const { history } = useRouter();

    function goHome(){
        history.push('/home'); // 跳转到首页

        history.push('/home',{ Id: 1 }); // 跳转到首页,并传参数
    }

    return (
        
    );
}

② 获取传参

import React from 'react';
import useRouter from 'use-react-router';

function Example() {
    const { history } = useRouter();

    useEffect(() => {
        // 获得传递过来的参数
        console.log(history.location.state);
        console.log(history.location.state.Id);
    }, [])

    return (
        
我是首页
); }

你可能感兴趣的:(使用React Hooks 16版本开发项目)