一、前言
昨天由于有一些事情耽搁,没有学习新的 react 以及发布博客. 而今天呢,这篇内容会分享类组件、函数式组件、hooks的一些方法以及初识 react 路由.接下来我们学习吧!
二、children
组件标签对之间的内容会被当做一个特殊的属性 props.children 传入组件内容
可以自定义结构的组件的常用形式 children
当你在组件中定义了标签,你可以在父组件中使用 this.props.children 来获取标签中输入的内容
代码案例 :
import React,{PureComponent} from 'react'
class Popwindows extends PureComponent{
render(){
console.log(this.props)
let {children} = this.props
return <div>{children}</div>
}
}
class App extends PureComponent{
render(){
return (
<div>
<Popwindows>
<h1>夏天快乐</h1>
<p>夏天都快过去了</p>
</Popwindows>
</div>
)
}
}
export default App;
浏览器效果 :

三、dangerouslySetInnerHTML
直接设置标签的 innerHTML
代码案例 :
import React,{PureComponent} from 'react'
let message = `<h1>欢迎各位伙伴来到我的博客</h1>`
class App extends PureComponent{
render(){
return (
<div dangerouslySetInnerHTML={{
__html:message
}}>
</div>
)
}
}
export default App;
浏览器效果 :

四、key 和 id
key是虚拟DOM对象的标识, 在更新显示时key起着极其重要的作用。
状态中的数据发生变化时,React 会进行新虚拟DOM 和 旧虚拟DOM 的diff比较 :
一. 旧虚拟DOM中找到了与新虚拟DOM相同的key:
(1).若虚拟DOM中内容没变, 直接使用之前的真实DOM
(2).若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM二, 旧虚拟DOM中未找到与新虚拟DOM相同的key
根据数据创建新的真实DOM,随后渲染到到页面
用index作为key可能会引发的问题:
一. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新,界面效果没问题, 效率低。
二. 如果结构中还包含输入类的DOM:
会产生错误DOM更新,界面有问题。
三. 果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的
怎样选择key值:
尽量在循环中避免使用 index 下标作为 key 值,我们可以使用后端传过来的 id,电话号码,编号都可以,因为都是唯一值
代码展示 :
import React,{PureComponent} from 'react'
class App extends PureComponent{
state = {
data:[
{
id:0,
content:"第1条数据"
},
{
id:1,
content:"第2条数据"
},
{
id:2,
content:"第3条数据"
},
{
id:3,
content:"第4条数据"
},
{
id:4,
content:"第5条数据"
},
{
id:5,
content:"第6条数据"
},
{
id:6,
content:"第7条数据"
},
]
}
render(){
let {data} = this.state;
return (
<div>
{
data.map((item,index)=>{
return <p key={item.id}>
{item.content}
<a onClick={()=>{
data = data.filter(itemData=>itemData!==item)
this.setState({
data:[...data]
})
}}>删除</a>
</p>
})
}
</div>
)
}
}
export default App;
五、hooks
React hooks 是React 16.8中的新增功能,无需编写类即可使用状态和其他React功能
官方文档 : https://reactjs.org/docs/hooks-intro.html
React Hooks 优势
简化组件逻辑
复用状态逻辑
无需使用类组件编写
Hook 使用规则
只在最顶层使用 Hook
只在 React 函数中调用 Hook
React 函数组件中
React Hook 中 - 我自己定义 hook 时,可以调用别的hook
所有的 hook 必须 以 use
六、useState
本身是一个函数,来自react包,参数和返回值,返回一个数组
参数:作用是给创建出来的状态一个默认值
返回值:数组
元素1:当前state的值
元素2:设置新的值时,使用的一个函数
let [状态的值,修改状态的方法] = useState(状态的初始值)
代码演示 :
app.js
import React,{useState} from 'react'
import Child from './Child'
/*
let [状态的值,修改状态的方法] = useState(状态的初始值)
*/
function App(){
// console.log(this);
let [data,setName] = useState({
name:"浩克",
age:28
})
return <div>
<Child data={data}/>
<button onClick={()=>{
setName({
name:"疯狂浩克",
age:data.age
})
}}>变身</button>
</div>
}
export default App;
创建一个Child.js组件
import React from 'react'
function Child(props){
let {data} = props;
return <div>
<h1>name:{data.name}</h1>
<h1>age:{data.age}</h1>
</div>
}
export default Child
我们看效果
|
|
七、useEffect
useEffect 可以解决生命周期臃肿的问题
useEffect 你更新了信息,会触发组件信息更新
没加return就是挂载,更新. 但是会先挂载
在 return 之后,就是卸载
在最后可以绑定监听一个变量,只有这些变量变动时,useEffect 才会执行
app.js
import React,{useState} from 'react'
import Child from './Child'
function App(){
let [data,setName] = useState({
name:"浩克",
age:28
});
let [show,setShow] = useState(true)
return <div>
{ show ? <Child data={data}/>:""}
<button onClick={()=>{
setName({
name:"疯狂浩克",
age:data.age
})
}}>变身</button>
<button onClick={()=>{
setShow(false)
}}>卸载</button>
</div>
}
export default App;
创建一个Child.js组件
import React,{useState,useEffect} from 'react'
function Child(props){
let {data} = props;
let [age,setAge] = useState(8)
// useEffect 你更新了信息,会触发组件信息更新
// 没加return就是挂载,更新. 但是会先挂载
// 在 return 之后,就是卸载
// 在最后可以绑定监听一个变量,只有这些变量变动时,useEffect 才会执行
// useEffect(()=>{
// console.log("组件更新了或者挂载了")
// return ()=>{
// console.log("卸载了")
// }
// },[age]);
useEffect(()=>{
console.log("挂载了")
},[]);
useEffect(()=>{
return ()=>{
console.log("卸载了")
}
},[])
useEffect(()=>{
console.log("更新了")
},[])
return <div>
<h1>name:{data.name}</h1>
<h1>age:{age}</h1>
<button onClick={()=>{
setAge(++age)
}}>点我加一岁</button>
</div>
}
export default Child
我们看效果

八、useRef
如果父组件想要调用子组件或者子组件里面的方法和数据的话,有时候就会用到useRef
useRef的特点 :
useRef返回一个ref对象,返回的ref对象在组件的整个生命周期保持不变
使用 useRef 需要注意:
useRef只能在类组件中使用 class x extends React.component 或者是PureComponent,否则会报错
案例 :
import React, {useState, useRef, createRef, useEffect } from 'react';
const Test = ()=>{
const [ index, setIndex ] = useState(1);
const createRefDiv = createRef();
const useRefDiv = useRef();
if(!createRefDiv.current){
createRefDiv.current = index;
}
if(!useRefDiv.current){
useRefDiv.current = index;
}
return(
<>
<div>createRefDiv.current: {createRefDiv.current}</div>
<div>useRefDiv.current: {useRefDiv.current}</div>
<div>
<button onClick={()=>setIndex(index+1)}>改变Index</button>
</div>
</>
)
}
export default Test;
九、useEffect与⾃定义Hooks
代码案例 :
app.js :
import react,{useEffect} from "react";
import {useSize,useScrollY} from "./hooks"
function App(){
let [scrollY,setY] = useScrollY();
useEffect(() => {
window.onscroll = ()=>{
setY(window.scrollY)
}
return () => {
window.onscroll = null;
}
}, [])
return <div>
<ul>
{
[...(".".repeat(100))].map((item,index)=>{
return <li key={index}>这是第{index}个li</li>
})
}
</ul>
<a onClick={()=>{
setY(100)
}}
style={{
position:"fixed",
top:"50px",
left:"200px"
}}
>{scrollY}</a>
</div>
}
export default App;
index.js :
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<App />,
document.getElementById('root')
);
hooks.js :
import React,{useState} from "react"
// 开头必须是 use
function useSize(){
return {
w: window.innerWidth,
h: window.innerHeight
}
}
// 获取滚动条 和 设置滚动条
function useScrollY(){
let [scrollY,setY] = useState(window.scrollY)
return [
scrollY,
(newScrollY)=>{
window.scrollTo(0,newScrollY);
setY(newScrollY)
}
]
}
export {useScrollY};
查看浏览器 :

当我们滑动鼠标滚轮时,就会自动获取到 scroll 的距离,然后点击那个数字,就会回到我们设置的 100 的那个距离
十、初识react路由
React Router4.0基本概述
React Router4.0(以下简称 RR4)遵循React的设计理念,即万物皆组件。所以 RR4 只是一堆 提供了导航功能的组件(还有若干对象和方法),具有声明式(声明式编程简单来讲就是你只需要关心做什么,而无需关心如何去做,可组合性的特点。
RR4 采用单代码仓库模型架构(monorepo),这意味者这个仓库里面有若干相互独立的包,分别是
react-router React Router 核心
react-router-dom 用于 DOM 绑定的 React Router
react-router-native 用于 React Native 的 React Router
react-router-redux React Router 和 Redux 的集成
react-router-config 静态路由配置的小助手
安装
第一步: 我们还是正常建立 react 项目
安装 React 框架 : npm i -g create-react-app
创建项目 : create-react-app 项目名称 (项目名称避免使用中文)
进入创建的项目路径 : cd 项目名字第二步: 下载安装 react 路由
在当前项目中下载路由
npm i -S react-router-dom
BrowserRouter 和 HashRouter
是什么?
- HashRouter:页面跳转原理是使用了location.hash、location.replace,并且路径中是包含/#
- BrowerRouter:页面跳转原理是使用了pushState、replaceState,路径不包含#直接定位到/目录下
区别?
- 从页面的地址栏中可以看出HashRouter是包含#号的,而BrowerRouter是不包含#号的
- BrowerRouter的开启需要后端配置的,类似于Vue中的history模式。HashRouter类型于Vue中的hash模式
怎么用?
import React from "react"
import ReactDOM from "react-dom"
// 引入 HashRouter
// import {HashRouter} from "react-router-dom";
// 引入 BrowserRouter
import {BrowserRouter} from "react-router-dom";
import './index.css';
import App from "./App"
ReactDOM.render(
// <HashRouter>
// <App />
// </HashRouter>,
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
)

十一、总结
今天学习了这么多方法,在写项目中权重挺高的,里面的注意点也希望大家能够注意.明天将会继续分享 react 的路由使用.
本文介绍了React函数式组件的基础知识,包括children属性、dangerouslySetInnerHTML的使用,以及key和id的重要性和选择。接着深入探讨了React Hooks,如useState、useEffect和useRef,阐述了它们的优势和用法。文章还简要讨论了自定义Hooks的实现,并初次接触了React Router 4.0,讲解了其基本概念和主要组件,包括BrowserRouter和HashRouter的区别和使用。
1320

被折叠的 条评论
为什么被折叠?



