React学习笔记

1. 起步

# 创建项目
npx create-react-app project-name

Vscode - React插件安装

image-20220518185309858

添加该依赖后:

rcc 和 rfc可以创建组件的方法

# 快速启动的代码块
rcc - react class component
rfc - react fucntion component

1.1 Hello world

// index.js

import react from 'react'
import ReactDOM from 'react-dom'
import App from './App.jsx'

ReactDOM.render(
    <App />
    , document.getElementById('root')
)
// App.js
import React from 'react'
import ReactDom from 'react-dom'


class App extends React.Component {
    render() {
        return (
            <ul>
                <li>hello world</li>
                <li>hello world</li>

            </ul>
        )
    }
}

export default App

1.2 JSX

JSX是JavaScript xml,语法上与html有些区别。

class改成className, for改成htmlFor…

所有的使用js语法的地方,都是大括号。

绑定样式

style={{ backgroundColor: 'red' }} 

// 第一层{}代表要使用js语法,第二层表明这是一个object
// 由于里面是JavaScript语法,所以需要写成驼峰命名法
1.2.1 for循环产生元素
const arr = ['刘备', '关羽', '张飞']

render(){
    return (
    	<div>
            {
                arr.map((item, index) => {
                    return <li key={index}>{item}</li>
                })
            }
        </div>
    )
}

// 特别备注:只有map有返回值,forEact返回值是undefined, 所以这里不能用forEach

1.3 React下绑定点击事件

import React, { Component } from 'react'

export default class App2 extends Component {
    state = {
        num: 1
    }
    render() {
        return (
            <div>
                num : {this.state.num}
                <br />
                {/* state */}
                <button onClick={() => this.setState({ num: this.state.num + 1 })}>累加</button>
                {/* 箭头函数不改变this的指向 */}
                <button onClick={() => this.addNum()}>累加</button>
                {/* 修改this的指向 */}
                <button onClick={this.addNum.bind(this)}>累加</button>
            </div>
        )
    }

    addNum() {
        this.setState({ num: this.state.num + 1 })
    }
}

2. 函数式编程

2.1 函数式版本的累加器

import React, { useState } from 'react'

// 函数式编程
export default function App3() {
    const [num, setNum] = useState(1);

    function add() {
        setNum(num + 1)
    }

    return (
        <div>
            <span>{num}</span>
            <br />
            <button onClick={add}>累加</button>
        </div >
    )
}

备注:所有以use开头的useXXX,都是Hook

2.2 useState

useState<number>(initialState: number | (() => number)): [number, React.Dispatch<React.SetStateAction<number>>]

2.3 useEffect

使用useEffect可以模拟Vue中的生命周期函数

// 模拟mouted
useEffect(() => {
    console.log('hello')
})


// 监控数据更新(模拟updated)
useEffect(() => {
    console.log('发生了改变')
}, [num])

// 第二个参数为 [], 意味着什么也不监控
// 第二个参数为 [num1,num2]


// 模拟beforeDestory
useEffect(() => {
    return () => {
        console.log('销毁阶段,该代码会执行')
    }
}, [num])

2.4 使用memo缓存组件

import React, { useState, memo } from 'react'

const Child = memo(() => {
    console.log('子组件更新 :>> ');
    return (
        <h2>子组件</h2>
    )
})

3. 参数传递

3.1 父传子

function Father(props) {
    return (
        <>
            <h1>Father</h1>
       		<span > num={props.num} </span>
        </>
    )
}


export default function App4() {
    return (
        <div>
            <Father num={2} />
        </div>
    )
}

// 备注:可通过属性将方法传递给子组件,实现修改父组件中的数据

3.2 context跨级组件传参

import React, { createContext } from 'react'

// 注册上传文环境
const Context = createContext()

function Child() {
    return (
        // 消费者组件
        <Context.Consumer>
            {
                (data) => {
                    console.log('data :>> ', data);
                    return (
                        <span>
                            {JSON.stringify(data)}
                        </span>
                    )
                }
            }
        </Context.Consumer>
    )
}

export default function App5() {
    return (
        // 提供者组件
        <Context.Provider value={{
            currUser: { name: 'jack' }
        }}>
            <Child></Child>
        </Context.Provider >
    )
}

3.3 实现v-model

// 实现v-model


export default function App7() {
    const [val, setVal] = useState('初始值')
    return (
        <div>
            <input type="text" value={val} onChange={(e) => setVal(e.target.value)} />
            <button onClick={() => console.log('val', val)}>获取当前的值</button>
        </div>
    )
}

4. react redux

4.1 安装依赖

npm i redux react-redux

4.2 基础示例

image-20220526220117081

store/index.js

import { createStore } from "redux"
import reducer from "./reducer"

const store = createStore(reducer)

export default store

store/reducer.js

const defaultState = {
    num: 100
}

export default (state = defaultState) => state

index.js

import { Provider } from "react-redux";
import store from './store'

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
    // 添加数据提供者
    <Provider store={store}>
        <React.StrictMode>
            <App />
        </React.StrictMode>
    </Provider>
);

connect映射值

import React from 'react'
import { connect } from 'react-redux'

function App9(props) {
    // 通过props拿到全局store中的值
    return (
        <h1>
            {props.num}
        </h1>
    )
}


const mapStateToProps = (state) => {
    return {
        num: state.num
    }
}

// 使用连接器, 映射值
export default connect(mapStateToProps)(App9)

4.3 调用函数和传递参数

reducer.js

const defaultState = {
    num: 1
}

export default function (state = defaultState, action) {
    const newState = JSON.parse(JSON.stringify(state))
    
	// action值传递
    switch (action.type) {
        case 'addNum':
            console.log('action :>> ', action);
            newState.num += (action.value)
            break
        default:
            break
    }

    return newState
}

import React from 'react'
import { connect } from 'react-redux'

function App9(props) {
    return (
        <>
            <h1>
                {props.num}
            </h1>
            <button onClick={props.addNum}>增加</button>
        </>
    )
}


const mapStateToProps = (state) => {
    return {
        num: state.num
    }
}

const mapDispathToProps = (dispatch) => {
    return {
        addNum() {
            // 触发action函数(可以传任意个参数,最终都会在action对象中)
            dispatch({ type: 'addNum', value: 2, randomValue: 999 })
        }
    }
}

// 使用连接器, 映射值
export default connect(mapStateToProps, mapDispathToProps)(App9)

5. react router

5.1 安装依赖

npm install react-router-dom@6

5.2 配置router

import { BrowserRouter, Routes, Route } from 'react-router-dom'
import App from '../App10'
import About from '../pages/About'
import Home from '../pages/Home'

const BaseRouter = () => {
    return (
        <BrowserRouter>
            <Routes>
                // path代表匹配路径 , element代表渲染的元素
                <Route path="/" element={<App />}>
                    <Route path="/home" element={<Home />}></Route>
                    <Route path="/about" element={<About />}></Route>
                </Route>
            </Routes>
        </BrowserRouter>
    )
}

export default BaseRouter

在index.js中引入router

image-20220527104406217

在需要使用的地方,配置<Outlet>,类似vue-router中的router-view。

用于渲染匹配的路由对应的文件内容。

import { Outlet } from 'react-router-dom'

export default function App10() {
    return (
        <div>
            <h1>
                App10
            </h1>

            <Outlet />
        </div>
    )
}

5.3 Link标签

类似于router-link,最终会被渲染成a标签

<ul>
<li> <Link to='/home'>首页</Link> </li>   // 实现界面跳转
<li> <Link to='/about'>关于</Link> </li>
</ul>

5.4 useLocation

用于访问当前路径

const location = useLocation()
function handleClick() {
console.log('location :>> ', location);
}

image-20220527115236977

5.5 路径参数

<Route path="/home" element={<Home />}>
    <Route path=':id' element={<></>}></Route> // 参数匹配
</Route>

const params = useParams()   // 获取参数
console.log('params :>> ', params);

5.6 搜索参数(?id=1)

const [searchParams] = useSearchParams()

console.log('id :>> ', searchParams.getAll('id'));  // 匹配所有的,返回数组
console.log('id :>> ', searchParams.get('id'));   // 只匹配第一个

for (let key of searchParams.keys()) {
	console.log('key :>> ', key);
}

5.7 事件跳转携带参数(携带大量数据)

const navigate = useNavigate()

navigate("/home", {
    state: [{ name: 'zhangsan' }, { name: 'lisi' }]
})

接收数据会在location中的state里

const location = useLocation()

image-20220527123008449

5.8 匹配404界面

// 用于匹配404界面
<Route path="*" element={<Error />}></Route>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏2同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值