柚子快報激活碼778899分享:學(xué)習(xí) 稍微學(xué)學(xué)react
文章開始前,先劃劃水~
今日份開心:
今天看之前發(fā)布的按鈕npm包下載量有162次,早知道好好做了
今日份不開心:
爬崗位看到一個整體都挺滿意的崗位,公司位置和發(fā)展大方向都好喜歡?。?!不過他的技術(shù)棧是react和nextjs的優(yōu)先,這兩個好像都沒學(xué)過。QAQ~~~~這就是傳說中的書到用時方恨少么?還有hybird跨段經(jīng)驗的優(yōu)先,這塊也沒有學(xué)過,?。∥以趺茨敲床耍。。ü方?emo中?。。。?/p>
現(xiàn)在學(xué)估計也來不及了,但是為了防止以后錯失良機,還是學(xué)學(xué)吧(最近其實超級想去學(xué)游戲引擎?。?/p>
先學(xué)學(xué)react吧,直接用黑馬的教案好了,前端我好像主要都是看的黑馬的教程,黑馬的主要特點就是講的比較細,教案比較完整,比較適合沒基礎(chǔ)的新人,有基礎(chǔ)的老人看的話可能會覺得又臭又長哈哈。
正片開始~??!
好幾個月沒學(xué)大的新技術(shù)棧了。學(xué)習(xí)啟動?。。。。。ó?dāng)寫到這個時候我還是個react小白)
其實以上的優(yōu)勢我覺得vue也具備···
項目開始
npx create-react-app react-basic
用慣了Vue看這個確實有點不習(xí)慣
知識點1.什么是JSX
JS和XML(HTML)的縮寫,是react中創(chuàng)建UI的方式,指的是在JS中編寫HTML
應(yīng)該就是用JS創(chuàng)建實例吧,并不是標(biāo)準(zhǔn)的JS寫法,其實還是每太理解作用
但看到下一個例子的時候就有點恍然大明白了,真的是吧JS和html融合了哈哈
基礎(chǔ)實例渲染+條件渲染(相當(dāng)于vue中的v-for和v-if吧)
知識點2.react事件綁定
講了基本用法和如何傳遞事件對象和參數(shù)
function App(){
const clickHandler = ()=>{
console.log('button按鈕點擊了')
}
return (
)
}
function App(){
const clickHandler = (e)=>{
console.log('button按鈕點擊了', e)
}
return (
)
}
function App(){
const clickHandler = (name)=>{
console.log('button按鈕點擊了', name)
}
return (
)
}
function App(){
const clickHandler = (name,e)=>{
console.log('button按鈕點擊了', name,e)
}
return (
)
}
知識點3.組件使用+小案例
useState,這段代碼我看著有點蒙。哈哈,先往下繼續(xù)看
從狀態(tài)修改規(guī)則來看,要替換才能重新渲染,只用count++這種修改而非替換,無法重新渲染
現(xiàn)在明白了,定義時第二個為替換函數(shù),專門用來替換狀態(tài)變量,即set個全新的對象
下面有個實例,npm? run start 啟動下項目
不得不說啟動的速度相比vue慢了不少、、
只看文檔不看視頻學(xué)還真有點費勁。火速去看了眼,發(fā)現(xiàn)是忘記了npm install下載依賴了·····
厘一下代碼······主要是在app.js完成結(jié)構(gòu),在app.scss完成樣式,json就是模擬數(shù)據(jù)庫使用
import { useState } from 'react'
import './App.scss'
import avatar from './images/bozai.png'
import orderBy from 'lodash/orderBy'
/**
* 評論列表的渲染和操作
*
* 1. 根據(jù)狀態(tài)渲染評論列表
* 2. 刪除評論
*/
// 評論列表數(shù)據(jù)
const defaultList = [
{
// 評論id
rpid: 3,
// 用戶信息
user: {
uid: '13258165',
avatar: '',
uname: '周杰倫',
},
// 評論內(nèi)容
content: '哎喲,不錯哦',
// 評論時間
ctime: '10-18 08:15',
like: 88,
},
{
rpid: 2,
user: {
uid: '36080105',
avatar: '',
uname: '許嵩',
},
content: '我尋你千百度 日出到遲暮',
ctime: '11-13 11:29',
like: 88,
},
{
rpid: 1,
user: {
uid: '30009257',
avatar,
uname: '黑馬前端',
},
content: '學(xué)前端就來黑馬',
ctime: '10-19 09:00',
like: 66,
},
]
// 當(dāng)前登錄用戶信息
const user = {
// 用戶id
uid: '30009257',
// 用戶頭像
avatar,
// 用戶昵稱
uname: '黑馬前端',
}
/**
* 導(dǎo)航 Tab 的渲染和操作
*
* 1. 渲染導(dǎo)航 Tab 和高亮
* 2. 評論列表排序
* 最熱 => 喜歡數(shù)量降序
* 最新 => 創(chuàng)建時間降序
*/
// 導(dǎo)航 Tab 數(shù)組
const tabs = [
{ type: 'hot', text: '最熱' },
{ type: 'time', text: '最新' },
]
const App = () => {
// 導(dǎo)航 Tab 高亮的狀態(tài)
const [activeTab, setActiveTab] = useState('hot')
const [list, setList] = useState(defaultList)
// 刪除評論
const onDelete = rpid => {
// 如果要刪除數(shù)組中的元素,需要調(diào)用 filter 方法,并且一定要調(diào)用 setList 才能更新狀態(tài)
setList(list.filter(item => item.rpid !== rpid))
}
// tab 高亮切換
const onToggle = type => {
setActiveTab(type)
let newList
if (type === 'time') {
// 按照時間降序排序
// orderBy(對誰進行排序, 按照誰來排, 順序)
newList = orderBy(list, 'ctime', 'desc')
} else {
// 按照喜歡數(shù)量降序排序
newList = orderBy(list, 'like', 'desc')
}
setList(newList)
}
return (
{/* 導(dǎo)航 Tab */}
評論
{/* 評論數(shù)量 */}
{list.length}
{/* 高亮類名: active */}
{tabs.map(item => {
return (
key={item.type}
className={
item.type === activeTab ? 'nav-item active' : 'nav-item'
}
onClick={() => onToggle(item.type)}
>
{item.text}
)
})}
{/* 發(fā)表評論 */}
{/* 當(dāng)前用戶頭像 */}
{/* 評論框 */}
{/* 評論列表 */}
{/* 評論項 */}
{list.map(item => {
return (
{/* 頭像 */}
className="bili-avatar-img"
src={item.user.avatar}
alt=""
/>
{/* 用戶名 */}
{/* 評論內(nèi)容 */}
{item.content}
{/* 評論時間 */}
{item.ctime}
{/* 評論數(shù)量 */}
點贊數(shù):{item.like}
{user.uid === item.user.uid && (
className="delete-btn" onClick={() => onDelete(item.rpid)} > 刪除
)}
)
})}
)
}
export default App
知識點4.數(shù)據(jù)綁定
可以通過綁定Dom或者綁定值來實現(xiàn)實時渲染
知識點5.組件通信
父傳子
function Son(props){
return
}
function App(){
const name = 'this is app name'
return (
)
}
子傳父
function Son({ onGetMsg }){
const sonMsg = 'this is son msg'
return (
{/* 在子組件中執(zhí)行父組件傳遞過來的函數(shù) */}
)
}
function App(){
const getMsg = (msg)=>console.log(msg)
return (
{/* 傳遞父組件中的函數(shù)到子組件 */}
)
}
兄弟組件:通過共同的父組件進行傳遞
// 1. 通過子傳父 A -> App
// 2. 通過父傳子 App -> B
import { useState } from "react"
function A ({ onGetAName }) {
// Son組件中的數(shù)據(jù)
const name = 'this is A name'
return (
this is A compnent,
)
}
function B ({ name }) {
return (
this is B compnent,
{name}
)
}
function App () {
const [name, setName] = useState('')
const getAName = (name) => {
setName(name)
}
return (
)
}
export default App
? 跨層傳遞
使用的createContext方法創(chuàng)建了一個上下文對象Ctx
頂層組件App通過Ctx.Provider組件提供數(shù)據(jù)
底層組件B用useContext鉤子獲取數(shù)據(jù)
// App -> A -> B
import { createContext, useContext } from "react"
// 1. createContext方法創(chuàng)建一個上下文對象
const MsgContext = createContext()
function A () {
return (
this is A component
)
}
function B () {
// 3. 在底層組件 通過useContext鉤子函數(shù)使用數(shù)據(jù)
const msg = useContext(MsgContext)
return (
this is B compnent,{msg}
)
}
function App () {
const msg = 'this is app msg'
return (
)
}
export default App
知識點6.副作用管理器 useEffect
用于Ajax請求 更改Dom操作等
在組件渲染完成后會從服務(wù)端獲取數(shù)據(jù)并顯示到頁面
useEffect(()=>{},[])
import { useEffect, useState } from "react"
function Son () {
// 1. 渲染時開啟一個定時器
useEffect(() => {
const timer = setInterval(() => {
console.log('定時器執(zhí)行中...')
}, 1000)
return () => {
// 清除副作用(組件卸載時)
clearInterval(timer)
}
}, [])
return
}
function App () {
// 通過條件渲染模擬組件卸載
const [show, setShow] = useState(true)
return (
{show &&
)
}
export default App
知識點7.自定義hook實現(xiàn)
自定義hook之前在學(xué)爬蟲的時候了解過一些,就是自定義函數(shù)
// 封裝自定義Hook
// 問題: 布爾切換的邏輯 當(dāng)前組件耦合在一起的 不方便復(fù)用
// 解決思路: 自定義hook
import { useState } from "react"
function useToggle () {
// 可復(fù)用的邏輯代碼
const [value, setValue] = useState(true)
const toggle = () => setValue(!value)
// 哪些狀態(tài)和回調(diào)函數(shù)需要在其他組件中使用 return
return {
value,
toggle
}
}
// 封裝自定義hook通用思路
// 1. 聲明一個以use打頭的函數(shù)
// 2. 在函數(shù)體內(nèi)封裝可復(fù)用的邏輯(只要是可復(fù)用的邏輯)
// 3. 把組件中用到的狀態(tài)或者回調(diào)return出去(以對象或者數(shù)組)
// 4. 在哪個組件中要用到這個邏輯,就執(zhí)行這個函數(shù),解構(gòu)出來狀態(tài)和回調(diào)進行使用
function App () {
const { value, toggle } = useToggle()
return (
{value &&
)
}
export default App
規(guī)則:只能在組件或者其他自定義hook中實現(xiàn),不能嵌套在if for 中
知識點8.redux
集中狀態(tài)管理工具,應(yīng)該和Vuex和pinia一個東西咯
npm i @reduxjs/toolkit ?react-redux?
0
import { createSlice } from '@reduxjs/toolkit'
const counterStore = createSlice({
// 模塊名稱獨一無二
name: 'counter',
// 初始數(shù)據(jù)
initialState: {
count: 1
},
// 修改數(shù)據(jù)的同步方法
reducers: {
increment (state) {
state.count++
},
decrement(state){
state.count--
}
}
})
// 結(jié)構(gòu)出actionCreater
const { increment,decrement } = counter.actions
// 獲取reducer函數(shù)
const counterReducer = counterStore.reducer
// 導(dǎo)出
export { increment, decrement }
export default counterReducer
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from './modules/counterStore'
export default configureStore({
reducer: {
// 注冊子模塊
counter: counterReducer
}
})
為react注入store
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
// 導(dǎo)入store
import store from './store'
// 導(dǎo)入store提供組件Provider
import { Provider } from 'react-redux'
ReactDOM.createRoot(document.getElementById('root')).render(
// 提供store數(shù)據(jù)
)
react組件使用store
修改store數(shù)據(jù)
柚子快報激活碼778899分享:學(xué)習(xí) 稍微學(xué)學(xué)react
參考文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。