React-Redux基础

node环境

node 环境:安装 Node >= 8.10 和 npm >= 5.6。
在这里插入图片描述

安装React环境

npm install -g create-react-app
在这里插入图片描述

创建react项目

cd 到所在文件夹
create-react-app 项目名
在这里插入图片描述
创建react项目成功
进入项目文件夹
cd reduxexample

通过Visual Studio Code启动
code .
在这里插入图片描述
在这里插入图片描述
启动项目,可以在控制台直接输入,也可以在Visual Studio Code中输入。
npm start
在这里插入图片描述
在这里插入图片描述
启动成功页面
安装ES7
在这里插入图片描述
在 src下创建components/Posts.js
在这里插入图片描述

输入rcc

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

Posts.js

import React, { Component } from 'react'

class Posts extends Component {
    constructor(props) {
        super(props);
        this.state = {
            posts: []
        }
    }
    componentDidMount() {
        fetch("https://jsonplaceholder.typicode.com/posts")
            .then(res => res.json())
            .then(
                data => this.setState({
                    posts: data
                })
            )
    }
    render() {
        const postItexms = this.state.posts.map(post => (
            <div key={post.id}>
                <h3>{post.title}</h3>
                <p>{post.body}</p>
            </div>
        ))
        return (
            <div>
                <h1>Posts</h1>
                {postItexms}
            </div>
        )
    }
}
export default Posts;


App.js

import React from 'react';

import Posts from './components/Posts';
import './App.css';

function App() {
  return (
    <div className="App">
      
      <Posts />
    </div>
  );
}

export default App;

fetch用法

fetch是用来取代传统的XMLHttpRequest的。 它的优点很多,包括链式调用的语法、返回promise等。

什么是fetch?

fetch api是基于promise的设计,它是为了取代传统xhr的不合理的写法而生的。

WHY fetch?

xhr请求写起来非常的混乱,如下所示:

var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';

xhr.onload = function() {
  console.log(xhr.response);
};

xhr.onerror = function() {
  console.log("Oops, error");
};

xhr.send();

但是使用fetch之后,如下所示:

fetch(url).then(function(response) {
  return response.json();
}).then(function(data) {
  console.log(data);
}).catch(function(e) {
  console.log("Oops, error");
});

这种链式调用的风格看上去会非常舒服。

如果我们再使用了箭头函数就会更加简洁了。

fetch(url).then(response => response.json())
  .then(data => console.log(data))
  .catch(e => console.log("Oops, error", e))

通过使用fetch api,可以将传统的xhr的粗糙的使用方法转化的如此精简,实在是好!

但是呢? 使用Promise,还是可以很明显看到callback的使用,不急,我们还可以使用 async、await :

// Async/Await requirements: Latest Chrome/FF browser or Babel: https://babeljs.io/docs/plugins/transform-async-to-generator/
// Fetch requirements: Latest Chrome/FF browser or Github fetch polyfill: https://github.com/github/fetch

// async function
async function fetchAsync () {
  // await response of fetch call
  let response = await fetch('https://api.github.com');
  // only proceed once promise is resolved
  let data = await response.json();
  // only proceed once second promise is resolved
  return data;
}

// trigger async function
// log response or catch error of fetch promise
fetchAsync()
    .then(data => console.log(data))
    .catch(reason => console.log(reason.message))

这样看上去是不是就好多了呢?

注意: 对于async和await的使用还是很明确的,就是一般我们在一个异步函数之前添加 await 关键词,然后在这个 await 的相关代码外面使用的时 async 函数,这样的结合才是合适的。

利用 async 和 await,我们就可以像写同步代码一样来写异步代码啦!

但是呢,目前async 和 await 的支持性还不是很好,目前还无法在一般的浏览器中使用!

基本使用方法:

fetch必须接受一个资源路径作为参数,并且返回了一个promise,所以我们可以直接使用链式调用的方式。

fetch("/getAllProduct").then(function(res) {
            return res.json();
        }).then(function (data) {
            if (data.code == 200) {
              console.log('获取到所有产品' ,data.data);
              that.props.addAllProduct(data.data);
            } else {
              console.log(data.message);
            }
        })

这样,我们就可以发送一个ajax请求。

/* 对客户端的返回数据封装
 * @param [code] (number) code为返回的状态码
 * @param [message] (string) message为返回的信息
 * @param [data] (any) data是可选的,为返回给前端的数据
 */
// 注意: retrunJson中的res为node处理接口的回调函数中的res,这个是必须的。
function returnJson(res, code, message, data) {
    var response = {
        code: code,
        message: message
    };
    if (typeof data !== 'undefined') {
        response.data = data;
    }
    res.json(response);   // 返回这个请求之后,必须要 res.end()表示请求的结束,否则后台可能会崩溃。
    res.end();
}

router.post('/register', function (req, res) {
    let userName = req.body.username,
        password = req.body.password,
        passwordAgain = req.body.passwordAgain,
        type = req.body.type;
    console.log(userName, password, type);
    if (type == 1) {
        if (password == passwordAgain) {
            let managerId = uuidv1();

            console.log(userName, password, passwordAgain);

            var newUser = new Manager({
                name: userName,
                password: password,
                type: req.body.type,
                managerId: managerId
            });

            Manager.find(userName, function (err, user) {
                if (err) {
                    returnJson(res, 5001, '服务器错误,注册失败');
                } else {
                    if (user !== null) {
                        returnJson(res, 4003, "此用户已经注册!");
                    } else {
                        // 如果符合条件,就注册该用户,将数据保存在数据库。
                        newUser.save(function (err, user) {
                            if (err) {
                                // 服务器端错误,失败返回状态码500
                                returnJson(res, 500, "用户注册失败!");
                            } else {
                                // user数据较简单,直接传递user即可,如果复杂,我们可以考虑使用对象形式传递更多数据。
                                returnJson(res, 200, "用户注册成功!", user);
                            }
                        });
                    }
                }
            });
        } else {
            returnJson(res, 4001, "用户两次输入密码不一致!");
        }
    } else if( type == 2) {

         if (password == passwordAgain) {
            let userId = uuidv1();

            console.log(userName, password, passwordAgain);

            var newUser = new User({
                name: userName,
                password: password,
                type: req.body.type,
                userId: userId
            });

            User.find(userName, function (err, user) {
                if (err) {
                    returnJson(res, 5001, '服务器错误,注册失败');
                } else {
                    if (user !== null) {
                        returnJson(res, 4003, "此用户已经注册!");
                    } else {
                        // 如果符合条件,就注册该用户,将数据保存在数据库。
                        newUser.save(function (err, user) {
                            if (err) {
                                // 服务器端错误,失败返回状态码500
                                returnJson(res, 500, "用户注册失败!");
                            } else {
                                // user数据较简单,直接传递user即可,如果复杂,我们可以考虑使用对象形式传递更多数据。
                                returnJson(res, 200, "用户注册成功!", user);
                            }
                        });
                    }
                }
            });
        } else {
            returnJson(res, 4001, "用户两次输入密码不一致!");
        }
    }
});

这样,我们就可以处理一个ajax请求。

注意点:

1、fetch() 返回的是一个Promise对象。

fetch使用的promise对象可以使得我们使用同步的方式写异步函数。

2、 fetch api是可以结合 async 和 await 来使用的。

fetch是基于promise实现的,但是使用promise的写法,我们还是可以看到callback的影子,如果结合 async和await来使用,还是非常不错的。

3、 Fetch api 提供的spi囊括但是不限于xhr的所有功能。

4、 fetch api 可以跨域。

参考: https://fetch.spec.whatwg.org/#http-cors-protocol

跨域请求必须包括 Origin 作为header.
  
  我们在发送fetch请求的时候就会使用到CORS协议,尽管这些对于开发者来说是透明的,但是浏览器还是会发送 origin 字段。
  
5、fetch提供了对request和response对象的通用定义。

Fetch 提供了对 Request 和 Response (以及其他与网络请求有关的)对象的通用定义。所以在一个Fetch请求中,完全可以只使用Request 和 Response两个对象,通过Request 设置参数,通过Response 对返回值进行处理。

所以,我们可以将一个fetch定义如下:

var myHeaders = new Headers();
myHeaders.append('Content-Type', 'image/jpeg');
var option = { method: 'GET',
    headers: myHeaders,
    mode: 'cors',
    cache: 'default' };
var myRequest = new Request('https://api.github.com/users/mzabriskie',option);
fetch(myRequest).then(function(response) {
    ... 
});

参考文章https://www.cnblogs.com/zhuzhenwei918/p/7249691.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值