Front End Learning Notes
Vue 和 React的区别
考点在于React的 虚拟Dom
Hooks
what is hook?
常用hook
useState
useEffect
useContext
useReducer
useCallback
useMemo
useRef
useLayoutEffect
useImperativeHandle
useDebugValue
自定义hook,并使用
What is SSR
如何防范SSR
快速上手React的Demo
用脚手架 快速初始化
1 npx craete-react-app my-react-app
启动项目
明确项目分布情况
源代码 src 目录
静态页面资源 public
关键文件
src下面的,
index 项目入口文件
该文件两个重要引入 React 和 ReactDOM
主要是通过 ReactDOM.createRoot方法 创建实例
通过render进行渲染
根组件 APP.js
react的组件就是函数组件形式(也有类组件,但是不推荐)
JSX 只能返回一个元素
变量插入值不是双引号内,而是{}内
1 2 3 4 5 6 7 8 9 10 function App() { const divContent = "content" const divTitle = "title" return ( <div title ={divTitle}>{divContent}</div> ); } export default App;
条件插入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function App() { const divTitle = "title" const flag = true; let divContent = null if (flag) { divContent = <p>flag为true</p> } else { divContent = <span>flag为false</span> } return ( <div title ={divTitle}> {divContent} </div> ); } export default App;
遍历 list.map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function App() { const list = [ { id: 1, name:'x1'}, { id: 2, name:'x2'}, { id: 3, name:'x3'} ] const listContent = list.map(item => ( <li key={item.id}>{item.name}</li> )) return ( <div >{listContent} </div> ); } export default App;
Fragment 每次增加其他行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import { Fragment } from "react"; function App() { const list = [ { id: 1, name:'x1'}, { id: 2, name:'x2'}, { id: 3, name:'x3'} ] const listContent = list.map(item => ( <Fragment> <li key={item.id}>{item.name}</li> <li>----------------</li> </Fragment> )) return ( <div >{listContent} </div> ); } export default App;
事件操作 和 setContent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import { useState } from "react"; function App() { let divContent = "Default Content" function handle(e) { console.log("press the button: ", e) setData("new Content") } const [data, setData] = useState("Default content") return ( <> <div>{data}</div> <button onClick={handle}>button</button> </> ); } export default App;
…data
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import { useState } from "react"; function App() { let divContent = "Default Content" function handle(e) { setData({ ...data, content: "new content" }) } const [data, setData] = useState({ title: "default title", content: "default content" }) return ( <> <div title={data.title}>{data.content}</div> <button onClick={handle}>button</button> </> ); } export default App;
增加元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import { useState } from "react"; function App() { let divContent = "Default Content" const [data, setData] = useState([ { id: 1, name:'x1'}, { id: 2, name:'x2'}, { id: 3, name:'x3'} ]) const listData = data.map(item => ( <li key={item.id}>{item.name}</li> )) let id = 3; function handle() { setData([ {id: ++id, name: "cat"}, // 前面加 ...data, // {id: ++id, name: "cat"} 后面加 ]) } return ( <> <ul>{listData}</ul> <button onClick={handle}>button</button> </> ); } export default App;
过滤功能filter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import { useState } from "react"; function App() { let divContent = "Default Content" const [data, setData] = useState([ { id: 1, name:'x1'}, { id: 2, name:'x2'}, { id: 3, name:'x3'} ]) const listData = data.map(item => ( <li key={item.id}>{item.name}</li> )) function handle() { setData(data.filter(item => item.id != 2)) } return ( <> <ul>{listData}</ul> <button onClick={handle}>button</button> </> ); } export default App;
自定义图片格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import { useState } from "react"; import image from './logo.svg' function App() { // const imageStyle = { // width: 100, // height: 100, // backgroundColor: "grey" // } const imgData = { className: "small", style : { width: 100, height: 100, backgroundColor: "grey" } } return ( <div> <img src={image} alt="" {...imgData} > </img> </div> ); } export default App;
传入参数式生成多个对象
请求功能所需的数据(例如文章信息) 创建 Article 组件进行遍历
将文章的数据分别传递给 Article
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 function Article(props) { return (<div> <h2> {props.title}</h2> <p>{props.content}</p> </div>) } function App() { return ( <> <Article title="title1" content="content1" /> <Article title="title2" content="content2" /> <Article title="title3" content="content3" /> <Article title="title4" content="content4" /> </> ); } export default App
解构方式,简化上述写法 + 层嵌套
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 function Detail({content, active}){ return ( <> <p>{content}</p> <p>state: {active ? "showing" : "hidden"}</p> </> ) } function Article({title, articleData}) { return (<div> <h2> {title}</h2> <Detail {...articleData}/> </div>) } function App() { const articleData = { title: "title1", detailData: { content: "content1", active: true } } return ( <> <Article {...articleData}/> </> ); } export default App;
父组件向子组件进行数据传递
注意 传递过去的数据都是 仅可读的,不可以修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 function List({ title, children, footer = <div>default bottom</div> }){ return ( <> <h2>{title}</h2> <ul>{children}</ul> {footer} </> ) } function App() { return ( <> <List title="list1" footer={<p>This the bottom content</p>} > <li>list item1</li> <li>list item2</li> <li>list item3</li> </List> <List title="list2" > <li>list itemA</li> <li>list itemB</li> <li>list itemC</li> </List> </> ); } export default App;
子组件向父组件传递
涉及到 回调函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import { useState } from "react"; function Detail({onActive}) { const [status, setStatus] = useState(false) function handle(){ setStatus(!status) onActive(status) } return( <div> <p style={{ display: status ? "block" : "none" }}>Detail的内容</p> <button onClick={handle}> button</button> </div> ) } function App() { function handleActive (status){ console.log(status) } return ( <> <Detail onActive={handleActive} /> </> ); } export default App;
同级组件传值, 借助 父组件进行中转
多层级组件传播,借助hooks
快速上手 JavaScript
下面是一个点击生成新的内容的快速展示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .change{ width: 100px; line-height: 100px; background-color: red; color: white; text-align: center; transition: all 1s; } </style> </head> <body> <div id="box">default content</div> <script> box.onclick = function (){ this.innerText = "new Content" this.className = "change" } </script> </body> </html>
拆为两个文件
1 2 3 4 5 <body> <div id="box">default content</div> <script src="quicklearn.js"> </script> </body>
文件名为 quicklearn.js
1 2 3 4 5 6 <script> box.onclick = function (){ this.innerText = "new Content" this.className = "change" } </script>
基本语法
1 2 3 4 5 6 // name var num = 10 var myAge = 18 var num1 = 20 var num2 = 30 // var myFriend
1 2 3 4 5 6 // data type var myNum = 10 //number var myStr = 'text' // string var myBool = true // boolean var myNull = null // Clear variable content var myUn // undefined, the default value
1 2 3 4 5 6 7 8 9 // operator var sum = 1 - 2 * 3 / 4 var resStr = "hello" + "javaScript" var isTrue = 21 > 3 // compare two items console.log(2 === 2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 // statement if (2 > 3) { console.log("i will execute") } else if (false) { console.log("i won't execute") } else { console.log("rest") } var sum = 0; for (var i = 0; i < 10; i++) { sum += i console.log(i) } console.log(sum) function getSum(start, end){ var sum = 0; for (var i = start; i <= end; i++) { sum += i } return sum } var res2 = getSum(100, 200) console.log(res2) //Nested functions function getSum2(start, end, fn){ var sum = 0; for (var i = start; i <= end; i++) { if(fn(i)) sum += i } return sum } var res3 = getSum2(1, 100, function (n) { if (n % 2 === 0) { return true } return false })
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // array var myArr = [10,20,30,40,50] console.log(myArr.length) console.log(myArr[0]) console.log(myArr[1]) console.log(myArr) // add element from end myArr.push(100) // from start myArr.unshift(200) console.log(myArr) // for each myArr.forEach(function (item, index) { console.log(item, index) })
1 2 3 4 5 6 7 8 9 10 11 // Object var obj = { name: "joe", age: 1 } console.log(obj) console.log(obj.name) for (var k in obj) { console.log(k, obj[k]) }
DOM 和 BOM
DOM叫做文档对象模型
BOM叫做浏览器对象模型
获取id,修改页面内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="block">default content</div> <p>default content</p> <p>default content</p> <p>default content</p> <p>default content</p> <script> var block = document.getElementById('block') console.log(block) block.textContent="JS set content" var contents = document.getElementsByTagName('p') console.log(contents) // contents[0].textContent = "the firsrt p title" var textArr = [ '震山的虎', '敏捷的豹', '远见的鹰', '善战的狼' ] for(var i = 0; i < contents.length; i++) { // contents[i].textContent = "new Content" contents[i].textContent = textArr[i] } </script> </body> </html>
采用document
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="block">default content</div> <div id="container"> <p>default content</p> <p class="item">default content</p> <p>default content</p> <p>default content</p> </div> <script> var block = document.getElementById('block') var contents = document.querySelectorAll('#container p') console.log(contents) var textArr = [ '震山的虎', '敏捷的豹', '远见的鹰', '善战的狼' ] for (var i = 0; i < contents.length; i++) { contents[i].textContent = textArr[i] } // 只具备单个item var secondItem = document.querySelector('.item') secondItem.textContent = '替罪的羊' // 前一个同级别的元素 secondItem.previousElementSibling.textContent = '划水的鱼' // 后一个同级别的元素 secondItem.nextElementSibling.textContent = '装饭的桶' // 父元素 var container = secondItem.parentElement console.log(container) // container.textContent = '新内容' // 替换所有的话 var items = container.children console.log(items) </script> </body> </html>
样式处理
下面是通过DOM修改block的样式
一共是两种方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } body { margin: 10px; } div { width: 100px; height: 100px; border: 1px dashed #ccc; margin-bottom: 10px; } .changesStyle{ width: 80px; height: 80px; background-color: tomato; } </style> </head> <body> <div id="block">default content</div> <script> // 样式处理 var block = document.querySelector('#block') // block.style.width = '80px' // block.style.height = '80px' // block.style.backgroundColor = 'tomato';// 修正属性名和颜色值 block.className = 'changesStyle' </script> </body> </html>
文本处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <head> <style> .bold-text { font-size: 20px; font-weight: 700; } </style> </head> <body> <div id="block">default content</div> <script> // 样式处理 var block = document.querySelector('#block') // 文本处理 block.innerHTML = "普通内容<span class='bold-text'>加粗文本</span>" </script>
事件处理
原始方式
1 2 3 4 var block = document.querySelector('#block') block.onclick = function () { alert("surprise again") }
新版, 相比原版,可以处理多个 点击事件
1 2 3 4 5 6 7 8 9 var block = document.querySelector('#block') // 事件处理 block.addEventListener('click', function () { alert('suprise!') }) block.addEventListener('click', function () { alert("surprise again!") })
网络请求
什么是网络请求
网络资源 从服务器 传送到 本地客户端
这样我们就能看到网页的内容了。
这每次一的传输就 是 网路请求。
网络请求方式
ajax
第三方工具 和 fetch API(替代ajax)
ajax
前端发送请求给后端
get例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 // or ajax const xhr = new XMLHttpRequest() xhr.open('GET', 'http://wuyou.com/common/get?name=wuyou&age=18') xhr.send() // 根据状态,触发function 改变 xhr.onreadystatechange = function () { // response 完成 if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { console.log(xhr.responseText) console.log(JSON.parse(xhr.responseText)) } }
get只能发纯文本数据
post可以发送各种各样的格式的数据
比如 图片, 视频等
要添加 发送给 服务器的数据是什么类型
post发送的参数在 send()中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const xhr = new XMLHttpRequest() xhr.open('POST', 'http://wuyou.com/common/post') // url-encoded 格式 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') xhr.send('name=wuyou&age=18') // 根据状态,触发function 改变 xhr.onreadystatechange = function () { // response 完成 if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { console.log(xhr.responseText) console.log(JSON.parse(xhr.responseText)) } }
Axios
使用第三方工具包简化 请求
下面以Axios为例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 const { default: axios } = require("axios"); // axios // axios.get("http://wuyou.com/common/get?name=吴悠&age=18") (async() => { // configure base address const ins = axios.create({ baseURL: "http://wuyou.com/common/" }) // 配置拦截器 // 请求拦截器 ins.interceptors.request.use(config => { console.log("发送了请求") return config }) ins.interceptors.response.use(res => { return res }) // 响应拦截器 const res = ins.get("get", { params: { name: 'wuyou', age: 18 } }) const res2 = await ins.post("post", { name: 'wuyou', age: 18 }) console.log(res1.data) console.log(res2.data) })
Fetch API
Fetch API
用来 代替原来的AJAX
get请求
1 2 3 4 5 6 7 8 9 10 11 12 const fetch = require('node-fetch'); fetch("http://wuyou.com/common/get?name=wuyou&age=18") .then(res => { if (res.ok) { return res.json() } }) .then(data => { console.log(data) })
POST请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const fetch = require('node-fetch'); fetch("http://wuyou.com/common/post", { method: 'POST', headers: { 'Content-Type' : 'application/json' }, // 将2javascript格式转为JSON body: JSON.stringify({ name: 'wuyou', age: 18 }) }) .then(res => { if (res.ok) { return res.json() } }) .then(data => { console.log(data) })
异步编程
Promise
将 异步 变为 同步, 返回数据
因为 前端 向 后端 发送请求之后, 需要等待一定时间,如果直接调用,会返回undefine
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function one(){ return 'I am One' } function two(){ setTimeout(() => { return 'I am Two' }, 3000) // 3s后返回 } function three(){ return 'I am Three' } function run() { console.log(one()) console.log(two()) console.log(three()) } run()
undefined是因为two函数没return,里面的return是settimeout的回调函数的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function one(){ return 'I am One' } function two(){ return new Promise((resolve, reject) => { setTimeout(() => { resolve("I am two") }) }) } function three(){ return 'I am Three' } function run() { console.log(one()) console.log(two()) console.log(three()) } run()
添加async 调用 和 await等待
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function one(){ return 'I am One' } function two(){ return new Promise((resolve, reject) => { setTimeout(() => { resolve("I am two") }) }) } function three(){ return 'I am Three' } async function run() { console.log(one()) console.log(await two()) // 等two() 执行完后,在进行three() console.log(three()) } run()
上面是解释Promise基本,下面是Poromise常用基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 //下面是 js 中 Promise 对象的基本用法 //创建一个 Promise 对象: const promise = new Promise((resolve, reject) => { // 异步操作 // 如果操作成功,调用 resolve 并传递结果值 // 如果操作失败,调用 reject 并传递错误信息 }); //使用 Promise 对象的 then() 方法处理操作成功的情况: promise.then((result) => { // 处理操作成功的情况,result 为操作的结果值 }); //使用 Promise 对象的 catch() 方法处理操作失败的情况: promise.catch((error) => { // 处理操作失败的情况,error 为错误信息 }); //可以链式调用 then() 方法,处理多个异步操作的情况: promise .then((result1) => { // 处理第一个异步操作的结果 return result1; }) .then((result2) => { // 处理第二个异步操作的结果 return result2; }) .then((result3) => { // 处理第三个异步操作的结果 return result3; }) .catch((error) => { // 处理操作失败的情况 });
TypeScript
官网: https://www.typescriptlang.org/
类型推断
类型注解
1 2 let str: string; str = 'abc';
指定输出参数类型
下面操作必须 自己知道 数组中 必然有元素 > 2的结果
否定 返回 undefined 会报错
1 2 3 let numArr = [1,2,5,4] let res = numArr.find(item => item > 2) as number console.log(res)
find
方法接受一个测试函数作为参数,这个测试函数对数组中的每个元素执行一次,直到找到一个使函数返回 true
的元素。在这个例子中,测试函数是 item => item > 2
,意味着 find
方法会查找数组中第一个大于 2 的元素。
指定分配类型
1 2 3 4 5 6 7 8 9 let v1: string = 'abc' let v2: number = 10 let v3: boolean = true let nu: null = null let un: undefined = undefined // 分配多个类型 let v4: string | null = null let v5: 1 | 2 | 3 = 2
1 2 let arr: number[] = [1 ,2 ,3] let arr1: Array<String> = ['a', 'b', 'c']
1 2 3 let t1: [number, string, number] = [1, 'a', 2] t1[0] = 1 // 指定位置必须为对应类型
增加?变为可选值
第三个值设为可选值之后,可以写,可以不写
1 let t1: [number, string, number?] = [1, 'a']
枚举类型
1 2 3 4 5 6 7 enum myEnum{ A, B, C } console.log(myEnum.A) // 0 console.log(myEnum[0]) // A
函数
1 2 3 function myFn(a: number, b: string): number{ return 100 }
? 设置节选
=是必选参数
必选放在最左边
可选放在右边
1 2 3 4 5 function myFn(a: number, b: string, c?: boolean, ...rest: number[]): number{ return 100 } const f = myFn(20, 'abc', true, 1, 2, 3)
接口
interface
1 2 3 4 5 6 7 8 9 10 11 12 13 14 interface Obj { name: string, age: number } const obj: Obj = { name: 'a', age: 10 } const obj2: Obj = { name: 'b', age: 11 }
type使用
1 2 3 type MyUserName = string | number let a: MyUserName = 10 let b: MyUserName = "azz"
泛型
1 2 3 4 5 6 7 function myFn<T>(a: T, b: T): T[] { return [a, b] } myFn<number>(1 ,2) myFn<String>("a", "b")
map方法总结
map是javascript中的用法,用于创建一个新的数组
新数组的每个元素都是对原数组中的每个元素调用一个提供的函数的结果。
1 arry.map (callback (curValue, index, array), thisArg)
Callback: 回调函数
curValue: 数组中处理的元素
index(可选): 当前元素索引
array(可选):数组本身
thisArg(可选): 执行callback时调用this的值
Eg:
1 2 3 const nums = [1 ,2 ,3 ,4 ];const nums2 = nums.map ((num ) => num * num)console .log (nums2)
React中使用map渲染
从数组中生成一组元素(如 JSX 元素)。它通常用于将一个数据数组转换为 JSX 元素数组,从而动态生成 UI。
1 2 3 4 5 6 7 8 9 10 11 const todos = [ {id: 1, value: "learn notes1"}, {id: 2, value: "learn notes2"}, {id: 3, value: "learn notes3"} ]; <ul> {todos.map((todo) => ( <li key={todo.id}>{todo.value}</li> ))} </ul>
todos.map(...)
:对 todos
数组的每个元素调用提供的箭头函数。
箭头函数 :(todo) => (<li key={todo.id}>{todo.value}</li>)
参数 todo
: todos
数组中的每一个对象。
返回值 :对每个 todo
对象,返回一个 <li>
JSX 元素,其中 key
属性是必需的,用于唯一标识每个列表项。
{todo.value}
:用于显示当前待办事项的文本内容。
箭头函数
ES6的函数简洁式表达方法。
基本语法
1 2 3 const functionName = (para1, para2, ... ) => { reutrn output; }
input: 入参数列表包裹在圆括号 ()
中。如果没有参数,可以省略括号;如果只有一个参数,可以省略圆括号。
箭头 =>
:用于分隔参数列表和函数体
函数体:
函数体包裹在花括号 {}
中。如果函数体只有一个简单的表达式,可以省略花括号和 return
关键字,返回值会被隐式返回。
Eg:
1 2 3 4 const sayHello => { console .log ("hello" ); } sayHello ();
1 2 3 4 5 6 const square = (x ) => { return x * x; } const square = x => x * x;}
1 2 3 4 5 const add (a, b) => { return a + b; } const add (a, b) => a + b;
常见用法
1 2 const nums = [1 ,2 ,3 ]const nums2 = nums.map ((num ) => n * n);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function Todo() { const [todos, setTodos] = useState([]); const [inputValue, setInputValue] = useState(''); function handleAdd() { const newTodo = { id: new Date().valueOf(), value: inputValue, completed: false } setTodos([...todos, newTodo]); setInputValue(''); } return ( <div> <h1>Todo List</h1> <button onClick={handleAdd}>Add Todo</button> <ul> {todos.map((todo)=> (<li key={todo.id}>{todo.value}</li>))} </ul> </div> ) }
箭头函数还有filter, reduce
filter
filter
会遍历原始数组中的每个元素,并将满足条件的元素放入新的数组中。
语法
1 const newArray = array.filter (callback (element, index, array), thisArg)
callback
:在数组每一项上调用的函数,该函数接收三个参数:
element
:数组中正在处理的当前元素。
index
(可选):当前元素的索引。
array
(可选):filter
方法被调用的数组本身。
thisArg
(可选):执行 callback
函数时用作 this
的值。
Eg:
1 2 const nums = [1 ,2 ,3 ,4 ,5 ];const evens = nums.filter ((num ) => num%2 === 0 );
过滤数组对象
1 2 3 4 5 6 const users = [ {name : 'b1' , age : 12 }, {name : 'b2' , age 18 }, ] const adults = users.filter ((user ) => user.age >= 18 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import React, { useState } from 'react'; function TodoApp() { const [todos, setTodos] = useState([ { id: 1, task: 'Learn React', completed: true }, { id: 2, task: 'Write Code', completed: false }, { id: 3, task: 'Read a book', completed: false }, { id: 4, task: 'Exercise', completed: true }, ]); const [showCompleted, setShowCompleted] = useState(false); // 过滤未完成的待办事项 const filteredTodos = todos.filter((todo) => !todo.completed); return ( <div> <h1>Todo List</h1> <button onClick={() => setShowCompleted(!showCompleted)}> {showCompleted ? 'Show All' : 'Show Incomplete'} </button> <ul> {(showCompleted ? todos : filteredTodos).map((todo) => ( <li key={todo.id}> {todo.task} {todo.completed ? '(Completed)' : ''} </li> ))} </ul> </div> ); } export default TodoApp;
reduce
input涉及绑定其值到组件的状态,并在输入变化时更新状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function InputEx() { const[inputValue, setInputValue] = useState(); const handleInput = (event) => { setInputValue(event.target.value); } return( <div> <h2>Control Input Example</h2> <input type="text" value={inputValue} onChange={handleInput} placeholder="Enter text here" /> </div> ) }
How to Implement TodoList Project
https://codesandbox.io/p/sandbox/sad-james-5jsd6n?file=%2Fsrc%2FTodo.js%3A85%2C47
谁无暴风劲雨时,守得云开见月明。