React知识点收尾及项目开始
hook
官网:React – A JavaScript library for building user interfaces
Hook 简介 – Reacthttps://zh-hans.reactjs.org/docs/hooks-intro.html
react拥有两种组件,类组件和函数组件,其中函数组件默认没有生命周期和状态数据,hook填补了这个空缺。
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
useState
没有状态数据的前提下,函数组件当中的数据修改后很难刷新
export default function layout(){
var msg = 0
const addMsg=()=>{
msg++
console.log(msg)
}
return <>
<p>{msg}</p>
<button onClick={addMsg}>加</button>
</>
}
使用useState
1、定义useState方法,然后传入初始值
2、useState会返回两个参数,分别是state数据和可以刷新设置数据的方法
import React, { useState } from 'react';
export default function Layout(){
const [count, setCount] = useState(0);
const addMsg=()=>{
setCount(count + 1)
}
return <>
<p>{count}</p>
<button onClick={addMsg}>加</button>
</>
}
如果state是多个数据,必须都发生修改,否则,没有修改的数据被置空覆盖了
import React, { useState } from 'react';
import img from "../asserts/image/1.jpg"
export default function Layout(){
const [count, setCount] = useState({isShow:1,title: "隐藏"});
const toggle = ()=>{
if(count.isShow){
setCount({title: "显示"})
}else{
setCount({isShow:1,title: "隐藏"})
}
console.log(count)
}
return <>
<p>
{
count.isShow===1?<img src={img} style={{width:"100px"}} />:""
}
</p>
<button onClick={toggle}>{count.title}</button>
</>
}
useEffect
作用: 可以让函数组件拥有自己的生命周期
useEffect会在组件第一次挂载完毕, 更新完毕, 组件即将卸载的时候自动触发,相当于类组件中componentDidMount , componentDidUpdate, componentWillUnmount三个钩子函数的集合
-
componentDidMount :组件初始化挂载之后,执行useEffict当中的语句,不执行useEffict当中返回的函数
-
componentDidUpdate :组件初始化挂载之后,先执行useEffict当中返回的函数,再执行useEffict当中的语句
-
componentWillUnmount:只执行useEffict当中返回的函数
import React, { useEffect,useState } from 'react';
export default function Home(){
let [state,setState] = useState("我是home组件")
useEffect(
()=>{
var obj = document.querySelector("#home_id")
console.log("我执行了",obj)
return ()=>{
console.log("我是home组件的嵌套函数,我执行了",obj)
}//这个函数在组件卸载前执行
}
)
const change = ()=>{
setState("hello,我确实是home组件")
}
return <>
<p id="home_id" onClick={change}>{state}</p>
</>
}
useEffect在所有组件内数据发送修改都执行,这个不合适。
useEffect拥有两个参数
-
第一个参数是一个操作函数,包含两部分,执行的语句,和返回的函数
-
第二个参数是一个数组,数组的元素是要监听的变量
import React, { useEffect,useState } from 'react';
export default function Home(){
let [state,setState] = useState("我是home组件")
let [hhh,setHhh] = useState("hhhh")
useEffect(
()=>{
var obj = document.querySelector("#home_id")
console.log("我执行了",obj)
return ()=>{
console.log("我是home组件的嵌套函数,我执行了",obj)
}
},[state]
)
const change = ()=>{
setState("hello,我确实是home组件")
}
const changeHhh = ()=>{
setHhh("哈哈哈")
}
return <>
<p id="home_id" onClick={change}>{state}</p>
<p id="home_id" onClick={changeHhh}>{hhh}</p>
</>
}
useEffict返回的函数通常用来回收内容。
import React, { useEffect,useState } from 'react';
var timer = ""
export default function Home(){
let [now,setTime] = useState(Date.now())
useEffect(
()=>{
return ()=>{
clearInterval(timer)
console.log("我是home组件的嵌套函数,我执行了")
}
},[]
)
const start= ()=>{
timer = setInterval(()=>{
setTime(Date.now())
},1)
}
const end=()=>{
clearInterval(timer)
}
return <>
<p>{now}</p>
<button onClick={start}>开始</button>
<button onClick={end}>停止</button>
</>
}
useReducer
作用: 可以让函数组件拥有自己的状态数据
-
参数1: 数据处理 函数reducer
-
参数2: 数据默认值
-
返回值: 数组
-
第一个元素: 状态数据对象
-
第二个元素: dispatch数据更新方法, dispatch可以发送一个数据操作对象action给数据处理函数reducer
-
代码如下:
import React, { useReducer } from 'react';
export default function Home() {
const reducer = (state, action) => {
var data = action.data
switch (action.type) {
case 'add':
var obj = state + data
return obj
case 'cut':
var objs = state - data
return objs
default:
return state
}
}
const [state, dispatch] = useReducer(reducer, 0)
const change_add = () => {
dispatch({type: 'add',data: 10})
}
const change_cut = () => {
dispatch({type: 'cut',data: 5})
}
return <>
<div style={{ width: "200px", margin: "0 auto" }}>
<button onClick={change_add}>增加</button>
<p>{state}</p>
<button onClick={change_cut}>减少</button>
</div>
</>
}
context
在复杂的嵌套情况下,组件之间传参不能很方便,所以需要有一个之间可以传参的方法,就是context
生成消费者模式
consumer(消费者)
第一种写法:
1、导入myContext
2、使用<myContext.Consumer>标签
3、标签内部需要由一个函数接受myContext的数据
4、使用数据
import React, { Component } from 'react'
import '../asserts/css/base.css'
import Father from './Father'
import myContext from '../utils/context'
export default class Grandpa extends Component {
state={
msg: "先辈参数 abc"
}
render() {
return (
<div className="grandpa">
我是先辈组件 --- 先辈参数 - {this.state.msg}
<br/>
<myContext.Consumer>
{
(context)=>{
console.log(context)
return <>
{
context.list.map(item=>(
<p key={item.id}>{item.name}</p>
))
}
</>
}
}
</myContext.Consumer>
<br/>
<Father msg={this.state.msg}></Father>
</div>
)
}
}
第二种写法:
import React, { Component } from 'react'
import '../asserts/css/base.css'
import Father from './Father'
import myContext from '../utils/context'
export default class Grandpa extends Component {
state={
msg: "先辈参数 abc"
}
static contextType = myContext //contextType固定写法
render() {
console.log(this.context)
return (
<div className="grandpa">
我是先辈组件 --- 先辈参数 - {this.state.msg}
<br/>
{
this.context.list.map(item=>(
<p key={item.id}>{item.name}</p>
))
}
<br/>
<Father msg={this.state.msg}></Father>
</div>
)
}
}
provider(生产者)
采用<myContext.Provider value={this.state.gList}>传递参数context
import React, { Component } from 'react'
import '../asserts/css/base.css'
import Father from './Father'
import myContext from '../utils/context'
export default class Grandpa extends Component {
state = {
msg: "先辈参数 abc",
gList: [
{
id: 4,
name: "净坛使者"
},
{
id: 3,
name: "浴皇大帝"
},
{
id: 2,
name: "揍死"
},
{
id: 1,
name: "如来"
},
]
}
render() {
console.log(this.context)
return (
<div className="grandpa">
我是先辈组件 --- 先辈参数 - {this.state.msg}
<br/>
<myContext.Provider value={this.state.gList}>
<myContext.Consumer>
{
(context)=>{
console.log(context)
}
}
</myContext.Consumer>
</myContext.Provider>
<br/>
<Father msg={this.state.msg}></Father>
</div>
)
}
}
确实在子组件当中调用context的结果
项目开始
项目创建
创建项目库
创建项目
create-react-app xumobile
安装依赖
npm i events react-router-dom@5.2.0 axios -S
调整结构
修改端口
封装axios
import { Component } from 'react'
import axios from 'axios'
axios.defaults.baseURL ="/api"
axios.interceptors.response.use(response=>{
return response.data
})
Component.prototype.$http = axios
export default axios
设置跨域
npm install --save-dev http-proxy-middleware@1.0
配置路由