reactive

一、跨层级传递

import { useContext, createContext, useState } from "react"

const msgContext = createContext()
function A(){
  const m = useContext(msgContext)
  return (
    <div>
      A-{m}
      <B></B>
    </div>
  )
}
function B(){
  const m = useContext(msgContext)
  return (
    <div>B-{m}</div>
  )
}

function App(){
  const message = 'my name is msg'
  return (
    <div>
      <msgContext.Provider value={message}>
        <A ></A>
      </msgContext.Provider>  
    </div>
  )
}

export default App 

二、useEffect

function App(){
  const [num,setNum] = useState(0)
  // 没有依赖项[],初始+组件更新,会执行
  // 空数组[],初始,会执行
  // 传入依赖项,初始+依赖项,会执行
  useEffect(()=>{
    console.log("副作用函数执行了")
  },[num])
  return (
    <div>
     <button onClick={()=>{setNum(num+1)}}>{num}</button>
    </div>
  )
}

三、清除副作用

function Son () {
  useEffect(()=>{
    const timer = setInterval(()=>{
      console.log("定时任务执行中...")
    },1000)
    // 清除副作用
    return () => {
      clearInterval(timer)
    }
  },[])
  return <div>this is son</div>
}

function App () {
    // 通过条件渲染模拟组件卸载
    const [show, setShow] = useState(true)
    return (
        <div>
            {show && <Son />}
            <button onClick={() => setShow(false)}>卸载Son组件</button>
        </div>
    )
}

四、自定义hook

函数名称用以use打头

function useToggle(){
  const [show, setShow] = useState(true)
  const toggle = () => setShow(!show)
  return {
    show,
    toggle
  }
}

function App () {
    const {show,toggle} = useToggle()
    return (
        <div>
            {show && <div>is dispaly</div>}
            <button onClick={toggle}>卸载Son组件</button>
        </div>
    )
}

 

image

 

五、redux

npx create-react-app react-redux

npm i @reduxjs/toolkit react-redux

目录结构

image

 counterStore.js

import { createSlice } from "@reduxjs/toolkit";
const createrStore = createSlice({
  name: 'counter',
  initialState: {
    counte: 10
  },
  reducers: {
    add(state){
      state.counte++
    },
    jian(state){
      state.counte--
    }
  }
})

const {add,jian} = createrStore.actions
const counterReducer = createrStore.reducer
export {add,jian}
export default counterReducer

state/index.js

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./modules/counterStore"
const store = configureStore({
  reducer: {
    counter: counterReducer
  }
})

export default store

index.js

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

<React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
 </React.StrictMode>

App.js

import { useSelector,useDispatch } from "react-redux"
import { add,jian } from "./store/modules/counterStore"
function App () {
    const {counte} = useSelector(state => state.counter)
    const dispath = useDispatch()
    return (
        <div>
          {counte}
          <button onClick={()=>dispath(add())}>+</button>
          <button onClick={()=>dispath(jian())}>-</button>
        </div>
    )
}


export default App

 传参数

action.payload 接收参数
addToNum(state,action){
        state.counte = action.payload
    },

异步

conterState.js

reducers: {
    updateLs(state,action){
        state.ls = action.payload
    }
}
// 异步
const {updateLs} = createrStore.actions
const url = 'http://geek.itheima.net/v1_0/channels'
const getGeek = () => {
    return async (dispatch) => {
        const res = await axios.get(url)
        dispatch(updateLs(res.data.data.channels))
    }
}
// 导出
export {getGeek}

app.js

import { useSelector, useDispatch } from "react-redux"
import { getGeek } from "./store/modules/counterStore"
import { useEffect } from "react"

const { ls } = useSelector(state => state.counter)

const dispath = useDispatch()
  useEffect(()=>{
    dispath(getGeek())
  },[dispath])

<div>{
        ls.map(item=><div key={item.id}>{item.name}</div>)
        }
</div>

 

六、router

配置

npm i react-router-dom

image

 Login/index.js

const Login = ()=>{
    return <div>  Login...  </div>
}

export default Login

router/index.js

import Login from '../page/Login'
import Article from '../page/Article'
import { createBrowserRouter } from 'react-router-dom'
const router = createBrowserRouter([
    {
        path: '/login',
        element: <Login/>
    },
    {
        path: '/article',
        element: <Article/>
    },
])

export default router
 index.js
import router from './router';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <RouterProvider router={router}></RouterProvider>
  </React.StrictMode>
);

声明式路由、编程式路由

import { Link,useNavigate } from "react-router-dom"
const Login = () => {
    const navigate = useNavigate()
    return (
        <div>  Login...
            {/* 声明式导航 */}
            <Link to='/article'>link to</Link>
            {/* 编程式导航 */}
            <button onClick={()=>navigate('/article')}>编程式导航</button>
        </div>
    )
}

export default Login

 

22

?

// page01
<button onClick={()=>navigate('/article?id=2&name=tom')}>编程式1</button>

// page02
import { useSearchParams,useParams } from "react-router-dom"
const [params] = useSearchParams()
let id = params.get('id')

/

// page01
<button onClick={()=>navigate('/article/123')}>编程式导航2</button>

// page02
import { useSearchParams,useParams } from "react-router-dom"
const params2 = useParams()
let id2 = params2.id

// router/index.js
const routdr = createBrowserRouter([
    {
        path: '/article/:id',
        element: <Article/>
    },
])

 

嵌套路由

image

 默认渲染二级路由

image

import { Link,Outlet } from "react-router-dom"
const Layout = ()=>{
    return (
        <div>
            <div>Layout</div>
            {/* 根目录默认渲染二级路由 */}
            <Link to='/'>login</Link>
            <br></br>
            <Link to='/article'>article</Link>
            <Outlet></Outlet>
        </div>
    )
}

export default Layout

 404

image

 

两种路由模式

image

 

七、安装包

npm i @reduxjs/toolkit react-redux react-router-dom dayjs classnames antd-mobile axios

npm i D sass

npm i lodash

npm install normalize.css

# react 18 版本

npm i react-quill@2.0.0-beta.2 --legacy-peer-deps 

八、配置联想提示路径

image

 npm i D @craco/craco

craco.config.js

const path = require('path')

module.exports = {
    webpack: {
        alias: {
            '@': path.resolve(__dirname,'src')
        }
    }
}

jsconfig.js

{
    "compilerOptions": {
        "baseUrl": "./",
        "paths": {
            "@/*": [
                "src/*"
            ]
        }
    }
}
"scripts": {
"start": "craco start",
"build": "craco build",
}

 

九、json-server

image

 

十、配置主题

image

 

<Button color="primary">11</Button>

十一、index.js 配置

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
// import App from './App';
import { RouterProvider } from 'react-router-dom';
import router from './router';
import { Provider } from 'react-redux';
import store from './store';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <RouterProvider router={router}></RouterProvider>
  </Provider>

  // <App />

);

 

十二、富文本编辑器

import ReactQuill from 'react-quill'
import 'react-quill/dist/quill.snow.css'

{/* //富文本 */}
                        <ReactQuill
                            className="publish-quill"
                            theme="snow"
                            placeholder="请输入文章内容"
                        />
                            
.publish-quill {
  .ql-editor {
    min-height: 300px;
  }
}

 

posted @ 2025-12-19 10:58  东方不败--Never  阅读(3)  评论(0)    收藏  举报