今后会有很多的修改动作都直接在组件中的store.dispatch()创建,当项目复杂的时候就比较难以管理,
所以redux希望使用专门的工厂函数来创建action
一般情况下采用actionCreator命名该文件
将该文件在需要使用的组件中进行引用并使用
该文件内容
//该文件夹是用来封装派发的
let jia=(newvalue)=>{
return {
type:"ONE",newvalue}
}
let jian=(newvalue)=>{
return {
type:"TWO",newvalue}
}
export default{
jia,
jian
}
需要使用的组件
//使用的时候
import aC from "../store/actionCreator"
add=()=>{
store.dispatch(aC.jia(2))
}
del=()=>{
store.dispatch(aC.jian(2))
}
一般情况下采用actionType命名该文件
并且创建常量用来存储该动作
在需要使用的地方进行引用使用(在actionCreate中也要进行修改
在该文件下
export const ONE="ONE"
export const TWO="TWO"
需要使用的文件下进行引用使用
import {
ONE,TWO} from "./actionType"
let jia=(newvalue)=>{
return {
type:ONE,newvalue}
}
let jian=(newvalue)=>{
return {
type:TWO,newvalue}
}
【今后项目的体积会变得很大,所有的操作就会写在一个reducer中,难以管理,所以一般将组件自己的reducer单独分离出来进行管理】
一般情况下采用组件名加R进行命名,
将原本放在reducer里的内容放到刚创建的文件中
新创建一个reducer的文件夹,文件夹里是各个组件的reducer
import {
ONE,TWO} from "./actionType"
let data = {
name: "嘎嘎",
age: 12
}
let homeR = (state = data, action) => {
switch (action.type) {
case ONE: return {
...state, age: state.age+action.newvalue}
break;
case TWO: return {
...state, age: state.age-action.newvalue}
break;
default: return state
break;
}
}
export default homeR
因为每个组都有自己的reducer,怎样将所有的reducer进行合并成一个【使用redux中的combineReducers方法】
//因为将所有的reducer划分到模块里了,所以需要将其整合到一起,发送给index里的入reducer
import {
combineReducers} from "redux"
import homeR from "../store/reducer/homeR"
let reducer=combineReducers({
homeR
})
export default reducer
// 先引入redux
import {
createStore } from "redux"
//合并之后的redux
import reducer from "./reducer"
let store = createStore(reducer)
export default store
第六步:切记不要忘记在使用的时候加上模块名,否则不显示数据
<h2>{
store.getState().homeR.age}</h2>
<h2>{
store.getState().homeR.name}</h2>
之前的写法redux与react的耦合度过于高。代码不够简洁(组件中出现了大量的store对象)
react-redux是一个插件,一个react的插件专门用来简化react应用中使用redux
使用:npm install --save react-redux
组件:把 store 提供给其子组件
import {
Provider}from "react-redux"
import store from "./store"
<Provider store={
store}>
<App />
</Provider>,
connect 高阶组件:链接 链接react组件和redux(组件状态要从redux中获取)
生成数据在props中
形参数是state的数据 当前函数必须return一个对象
import React, {
Component } from 'react'
import {
connect } from "react-redux"
class demon extends Component {
constructor(props) {
super(props)
this.state = {
}
}
render() {
return (
<div>
<h1>页面</h1>
</div>
)
}
}
export default connect(state => ({
state }))(demon)
<h5>{
this.props.state.demoR.name}</h5>
import aC from "../store/actionCreator"
fun=()=>{
this.props.dispatch(aC.update("我是你意想不到的值,你心心念念的那个值"))
}
<h5>{
this.props.state.demoR.name}</h5>
<button onClick={
this.fun}>点击变名字</button>
修改store里的actioncreator等值
ajax可以放在 componentDidMount方法中的代码,
是在组件已经完全挂载到网页上才会调用被执行,所以可以保证数据的加载。
此外,在这方法中调用setState方法,会触发重新渲染。所以,官方设计这个方法就是用来加载外部数据用的
【在react16.0以后,componentWillMount可能会被执行多次。所以最好不要在此钩子中请求】
React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据时可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI
【React本身没有独有的获取数据的方式。(使用原生或者第三方的方式)】
//练习请求地址:
http://api.artgoer.cn:8084/artgoer/api/v1/user/324380/v3/topic/topicHomeByLabel?pageIndex=1&token=b544cd63-6d42-46fe-a96c-3cf96bae3113&topicId=62187
jQuery 比较重,需要外部引用不建议使用
axios 轻量级,建议使用
式)】
//练习请求地址:
http://api.artgoer.cn:8084/artgoer/api/v1/user/324380/v3/topic/topicHomeByLabel?pageIndex=1&token=b544cd63-6d42-46fe-a96c-3cf96bae3113&topicId=62187
jQuery 比较重,需要外部引用不建议使用
axios 轻量级,建议使用
fetch 原生函数,但老版本浏览器不支持
ajax可以放在 componentDidMount方法中的代码,
是在组件已经完全挂载到网页上才会调用被执行,所以可以保证数据的加载。
此外,在这方法中调用setState方法,会触发重新渲染。所以,官方设计这个方法就是用来加载外部数据用的
【在react16.0以后,componentWillMount可能会被执行多次。所以最好不要在此钩子中请求】
React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据时可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI
【React本身没有独有的获取数据的方式。(使用原生或者第三方的方式)】
//练习请求地址:
http://api.artgoer.cn:8084/artgoer/api/v1/user/324380/v3/topic/topicHomeByLabel?pageIndex=1&token=b544cd63-6d42-46fe-a96c-3cf96bae3113&topicId=62187
jQuery 比较重,需要外部引用不建议使用
axios 轻量级,建议使用
fetch 原生函数,但老版本浏览器不支持
http://api.artgoer.cn:8084/artgoer/api/v1/user/324380/v3/topic/topicHomeByLabel?pageIndex=1&token=b544cd63-6d42-46fe-a96c-3cf96bae3113&topicId=62187
第一步:下载axios模块,npm install --save-dev axios
【使用流程和在vue中使用一样】
第一步:封装拦截器【固定写法】
import axios from "axios"
// 创建axios 赋值给常量service
const service = axios.create();
// 添加请求拦截器(Interceptors)
service.interceptors.request.use(function (config) {
// 发送请求之前做写什么
return config;
}, function (error) {
// 请求错误的时候做些什么
return Promise.reject(error);
});
// 添加响应拦截器
service.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
export default service
第二步:封装post请求
import service from "../util/service"
export function getlink(url,data) {
return new Promise((resolve, reject) => {
service.request({
url,
method: "post",
data
}).then((ok) => {
resolve(ok)
}).catch((err) => {
reject(err)
})
})
}
第三步:在组件中使用post请求
使用qs库或者或 URLSearchParams传参数
import React, {
Component } from 'react'
import {
getlink } from "../api/postapi"
import qs from "qs"
export default class index extends Component {
fun=()=>{
//使用qs库进行post传参
let data=qs.stringify({
//给后端传递的参数
name:"好好恰饭"
}) getlink("http://localhost:8000/post/post",data).
then((ok)=>{
console.log(ok)
})
}
}
第四步:解决跨域
找/node_modules/react-scripts/config/webpackDevServer.config.js,配置proxy就好
import service from "../util/service"
export async function aslink(url,data){
return await service.request({
url,
method:"post",
data
})
}
//使用的时候和axios一样
【注意,使用* as】
import * as postlink from "../api/async"
fun=()=>{
//使用qs库进行post传参
let data=qs.stringify({
name:"你也是个憨憨"
})
//要打点进行调用
postlink.aslink("/api/post/post",data).then((ok)=>{
console.log(ok)
})
}
XMLHttpRequest的最新替代技术——Fetch API, 它是W3C的正式标准 (xx.json转换成json字符串)
使用步骤和axios一样,不过就是使用的时候
3.1:fetch的get请求
fun=()=>{
fetch("http://api.artgoer.cn:8084/artgoer/api/v1/user/324380/v3/topic/topicHomeByLabel?pageIndex=1&token=b544cd63-6d42-46fe-a96c-3cf96bae3113&topicId=62187")
.then(req=>req.json())
.then((ok)=>{
console.log(ok)
})
}
第一步:下载jquery模块 npm install --save-dev jquery
第二步:引用 import $ from “jquery”
第三步:使用
let that=this;
$.ajax({
url:"http://api.artgoer.cn:8084/artgoer/api/v1/user/324380/v3/topic/topicHomeByLabel?pageIndex=1&token=b544cd63-6d42-46fe-a96c-3cf96bae3113&topicId=62187",
type:"GET",
dataType:"json",
success(ok){
console.log(ok.data.commentList[0].commentTxt)
that.setState({
text:ok.data.commentList[0].commentTxt
})
}
})
传统的Ajax:指的是 XMLHttpRequest,最早出现的发送后端请求技术,
隶属于原始js,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱
axios:是一个基于Promise,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范
fetch:不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象
正向代理—>开发环境
第一步:找/node_modules/reactscripts/config/webpackDevServer.config.js
第二步:
proxy:{
"/api(可以随便写)":{
target:"请求地址",
changeOrigin:true,
"pathRewrite":{
"^/api(和上面一样)":"/"
}
}
}
第三步:修改请求地址
反向代理—>上线环境
主要是因为,在解决跨域的时候配置文件隐藏过于深,寻找起来比较麻烦
使用弹射eject将配置文件设置到根目录来【切记不要使用】
eject 操作是不可逆的,执行之后会把所有细节都暴露在我们面前,让项目目录变得很庞大。所以不要一上项目就弹射
使用步骤:
第一步:项目目录执行:npm run eject【注意会报错】
第二步:解决报错
第三步:直接可以在当前的webpackdevserver.js文件夹中修改
async是异步的意思,用于申明一个 function 是异步的
await是等待异步结束的意思:而 await 用于等待一个异步方法执行完成。
【注意】await只能出现在async函数中
async 函数返回的是一个Promise对象。如果在函数中return一个值,async 会把这个值通过Promise.resolve()封装成 Promise 对象
async function fun(){
return "nihao"
}
//返回一个promise对象
//Promise{}
console.log(fun())
async 函数返回的是一个 Promise 对象,在最外层不能用 await 获取其返回值的情况下then() 来处理这个 Promise 对象
async function fun(){
return "nihao"
}
fun().then((ok)=>{
console.log(ok)
})
一般来说,认为 await 是在等待一个 async 函数完成。
不过按语法说明,await 等待的是一个表达式,
这个表达式的计算结果是 Promise 对象或者其它值
因为 async 函数返回一个 Promise 对象
所以 await 可以用于等待一个 async 函数的返回值
优势
async和await可以说是异步终极解决方案了,相比直接使用Promise来说,优势在于处理then的调用链,能够更清晰准确的写出代码,毕竟写一大堆then也很恶心,并且也能优雅地解决回调地狱问题。