前言
没有学习过react的其他版本,这次仅仅是针对react18上的开发方式做一个笔记,归纳总结
起步
- 直接上react的脚手架,my-app是你的项目名,这里有好几种创建react脚手架的命令,这里我选的是第一种,也是react官网建议用于学习用途的一种。另外几种创建方式有它自己的优势,详情可以阅读官网。
1.npx create-react-app my-app
2.npx create-next-app
3.npx create-remix
4.npx create-gatsby
5.npx create-expo-app
- 项目初始化后的文件
和vue对比的话,其实大差不差,有一些学习时候用不着的文件,删除后,就剩下index.js这个入口文件,和app.js这个ui文件了,然后将app.js改成app.jsx,这样可以更好的支持jsx语法。
用函数式组件编写react代码
1. 函数式组件写法
开始学习react的写法前,react是有类组件和函数式组件的写法差异的,在官网上目前都是推荐函数式写法,所以这次学习笔记并没有记录类组件的写法。
你可以声明任意一个函数,函数命名需要以大写字母开头(规范),该函数最后return的是一段jsx模板。这个便是一个函数式的组件,并将该函数导出。
注意,返回的jsx中,必须要有一个根节点包裹着,可以用空的根节点包裹<></>
function App () {
return (
<div>
Hello,word
</div>
);
}
export default App;
绑定方法和用useState声明数据
1. 绑定方法
- react中,在jsx中使用动态的数据或者方法,我们需要在对应的位置用一对大括号将变量给包裹起来{}。
function App () {
let num = 0
const handleClickAdd = ()=>{
num++
console.log(num)
}
return (
<div>
<div>当前num值:{num}</div>
<button onClick={handleClickAdd}>点我+1</button>
</div>
);
}
export default App;
2. hook-useState声明数据
- react中,如果我们想要通过改变数据,视图也同步改变的话,我们需要使用useState这个api。它接受一个初始的值,可以是数字,字符,对象,数组等。该函数返回的是一个2位长度的数组,第一位是该变量的名称,第二位则是用于修改对应变量的方法。我们需要在修改对应的数据时,通过解构出来的set方法去修改该数据,此时,页面就会跟着重新渲染。
import { useState } from 'react'; //导入对应的api
function App () {
let [num, setNum] = useState(0) //解构出变量和设置变量的方法
const handleClickAdd = () => {
setNum(num + 1)
console.log(num)
}
return (
<div>
<div>当前num值:{num}</div>
<button onClick={handleClickAdd}>点我+1</button>
</div>
);
}
export default App;
3. 函数如何传参
- 关于函数如何传递参数,这块需要在jsx中对函数进行改写,将原来的函数用箭头函数包裹起来,并进行传参。
import { useState } from 'react'; //导入对应的api
function App () {
let [num, setNum] = useState(1)
const handleClickAdd = (perValue) => {
setNum(num + perValue)
console.log(num)
}
return (
<div>
<div>当前num值:{num}</div>
<button onClick={()=>handleClickAdd(num)}>点我+{num}</button>
</div>
);
}
export default App;
4. hook-useState需要注意的
- 请勿直接修改state的值,请将state当成只读的,api返回的set方法是将传入的新值覆盖旧值的
- 减少state的声明,如要实现 a+b=c,你并不需要将3个变量都声明为state,请仔细考虑需求中哪些变量应该作为state
组件间传值通信
1. 组件间如何嵌套
像写html一样,我们只需要抽象的理解为,在某一个函数组件里,引用了另一个函数组件并返回,那么被引用的函数组件就成为了该函数组件的子组件。
function ImgShowBox () {
return (
<img src="" alt="" />
)
}
function ImgListBox () {
return (
<div>
<ImgShowBox></ImgShowBox> {/* 该组件为子组件 */}
</div>
)
}
export default ImgListBox
2. 如何传值给父组件
只需要在子组件中,写上对应传递的名字和变量即可,该值可以是静态的,也可以是动态的
import { useState } from 'react'; //导入对应的api
function ImgShowBox () {
return (
<img src="" alt="" />
)
}
function ImgListBox () {
let [url,setUrl] = useState("")
return (
<div>
<button>上一张</button>
<button>下一张</button>
<ImgShowBox mySrc={url} name="一张图片"></ImgShowBox> {/* 该组件为子组件 */}
</div>
)
}
export default ImgListBox
3. 如何接收子组件的值
我们可以通过props来进行父子组件的通信,用法很简单,每一个函数组件都会接收一个props的形参,该形参包含了父组件传递的参数。
\
import { useState } from 'react'; //导入对应的api
//解构赋值获取参数,并设定默认值
function ImgShowBox ({ url = "", name = "" }) {
return (
<div>
<button>不看了</button>
<img src={src} alt="" />
</div>
)
}
function ImgListBox () {
let [url, setUrl] = useState("")
return (
<div>
<button>上一张</button>
<button>下一张</button>
<ImgShowBox mySrc={url} name="一张图片"></ImgShowBox> {/* 该组件为子组件 */}
</div>
)
}
export default ImgListBox
4. 如何让子组件更新props的值
我们只需要在父组件中定义好对应更新props的方法,并将该方法通过props传入即可
import { useState } from 'react'; //导入对应的api
//解构赋值获取参数,并设定默认值
function ImgShowBox ({ url = "", name = "",noShowImg}) {
return (
<div>
<button onClick={()=>{noShowImg("不想看了")}}>不想看了</button>
<img src="" alt="" />
</div>
)
}
function ImgListBox () {
let [url, setUrl] = useState("https://一个图片地址")
const noShowImg = (value) =>{
setUrl("")
}
return (
<div>
<button>上一张</button>
<button>下一张</button>
<ImgShowBox mySrc={url} name="一张图片" noShowImg={noShowImg}></ImgShowBox> {/* 该组件为子组件 */}
</div>
)
}
export default ImgListBox
5 如何设置props的类型和默认值
使用prop-types插件
条件渲染和循环渲染(类比vue的v-if和v-for)
1. 如何进行条件渲染
这里用了2种不同的写法,一个直接在jsx上判断,一个通过函数调用返回不同的jsx
import { useState } from 'react'; //导入对应的api
function App () {
let data = [
{ content: "吃饭", complete: false },
{ content: "洗澡", complete: true },
{ content: "刷牙", complete: false },
]
const setIsCompleteDom = (flag) => {
if (flag) {
return (
<span>完成√</span>
)
} else {
return (
<span>未完成X</span>
)
}
}
return (
<div>
<p>
<span>待办:{data[0].content}</span>
{
setIsCompleteDom(data[0].complete)
}
</p>
<p>
<span>待办:{data[1].content}</span>
{data[1].complete ? <span>完成√</span> : <span>未完成X</span>}
</p>
<p>
<span>待办:{data[2].content}</span>
{data[2].complete ? <span>完成√</span> : <span>未完成X</span>}
</p>
</div>
);
}
export default App;
2. 如何进行循环渲染
归根到底,其实就是我们要通过js的方法,去循环遍历一个数据,组装好一段jsx。我们这里要特别注意,这个key要确保唯一性。
import { useState } from 'react'; //导入对应的api
function App () {
let data = [
{ content: "吃饭", complete: false },
{ content: "洗澡", complete: true },
{ content: "刷牙", complete: false },
]
const setIsCompleteDom = (flag) => {
if (flag) {
return (
<span>完成√</span>
)
} else {
return (
<span>未完成X</span>
)
}
}
const setToDoJSX = () => {
return data.map(item => {
return (
<li key={item.content}>
<span>{item.content}</span>
{setIsCompleteDom(item.complete)}
</li>
)
})
}
return (
<div>
<ul>
{setToDoJSX()}
</ul>
</div>
);
}
export default App;