diff --git a/practise/31.hook/01.useState的基础使用.jsx b/practise/31.hook/01.useState的基础使用.jsx new file mode 100644 index 0000000..1bc3408 --- /dev/null +++ b/practise/31.hook/01.useState的基础使用.jsx @@ -0,0 +1,40 @@ +/* useState +1.导入 useState 函数 (从 react 导入) +2.执行这个函数并且传入初始值,必须在函数组件中 +3.解构: [数据,修改数据的方法] +4.使用数据 修改数据 */ + +/* 状态的读取和修改 + const [count, setCount] = useState(0) +1.useState 传过来的参数作为 count 的初始值 +2. [count, setCount] 这里的写法是一个解构赋值,useState 返回值是一个数组 +3. [] 里面的值名字可以自定义,保持语义化 +4. [] 里面的值顺序不能更换,第一个参数是数据状态,第二参数是修改数据的方法 +5. setCount 函数作用用来修改 count, 依旧保持不能直接修改原值,要生成一个新值替换原值。setCount(基于原值计算得到的新值) +6. count 和 setCount 是一对的,绑定在一起的,setCount 只能用来修改对应的 count 值 */ + +/* 组件的更新 +当调用 setCount 的时候,更新过程: + +首次渲染: +首次被渲染的时候,组件的内部代码会被执行一次,其中 useState 也会跟着执行,重点注意:初始值只在首次渲染是生效 + +更新渲染 setCount 都会更新 +1. app 组件会再次渲染,这个函数会再次执行 +2. useState 再次执行,得到的新的 count 值不是 0 ,而是修改之后的 1,模板会用新值渲染 + +重点:useState 初始值只在首次渲染生效,后续只要调用 setCount,整个 app 中代码都会执行,此时的 count 每次拿到的都是最新值 +*/ + +import { useState } from 'react' + +function App () { + const [count, setCount] = useState(0) // 0 是初始值 + return ( +
+ +
+ ) +} + +export default App diff --git a/practise/31.hook/02.useState的使用2.jsx b/practise/31.hook/02.useState的使用2.jsx new file mode 100644 index 0000000..723304c --- /dev/null +++ b/practise/31.hook/02.useState的使用2.jsx @@ -0,0 +1,27 @@ +import { useState } from 'react' + +/* useState 注意事项 : +1.只能出现在函数组件中 +2.不能嵌套在if/for/其它函数中(react按照hooks的调用顺序识别每一个hook) */ + +function App () { + const [count, setCount] = useState(0) // 0 是 count 的初始值 + const [flag, setFlag] = useState(true) // true 是 flag 的初始值 + const [list, setList] = useState([]) // [] 是 list 的初始值,是一个空数组 + + function test () { + setCount(count + 1) + setFlag(false) + setList([1, 2, 3]) + } + + return ( +
+ count: {count}
+ flag: {flag ? '1' : '0'}
+ list: {list.join('-')} +
+ ) +} + +export default App diff --git a/practise/31.hook/03.useEffect副作用.jsx b/practise/31.hook/03.useEffect副作用.jsx new file mode 100644 index 0000000..a8a60b8 --- /dev/null +++ b/practise/31.hook/03.useEffect副作用.jsx @@ -0,0 +1,25 @@ +import { useState, useEffect } from 'react' + +// useEffect函数,作用就是为 react 函数组件提供副作用处理的 + +/* 在修改数据之后,把 count 值放在页面标题中 +1.导入 useEffect 函数 +2.在函数组件中执行,传入回调,并且定义副作用 +3.当通过修改状态更新组件时,副作用也会不断执行 */ + +function App () { + const [count, setCount] = useState(0) // 0 是 count 的初始值 + + useEffect(() => { + // 定义副作用 + document.title = count + }) + + return ( +
+ +
+ ) +} + +export default App diff --git a/practise/31.hook/04.useEffect依赖项.jsx b/practise/31.hook/04.useEffect依赖项.jsx new file mode 100644 index 0000000..8468e41 --- /dev/null +++ b/practise/31.hook/04.useEffect依赖项.jsx @@ -0,0 +1,50 @@ +import { useState, useEffect } from 'react' + +// useEffect函数,作用就是为 react 函数组件提供副作用处理的 + +/* 依赖项控制副作用的执行时机 +1.默认状态(无依赖项):组件初始化的时候先执行一次,等到每次数据修改组件更新再次执行 + +2.添加一个空数组依赖项,组件初始化的时候执行一次 + +3. 依赖特定项:组件初始化的时候执行一次,依赖的特定项发生变化会再次执行 + +4.注意事项:只要 useEffect 回调函数中用到的数据状态就应该出现在依赖项数组中声明,否侧可能会有 bug + +hook 的出现就是在不用生命周期的概念也可以写业务代码 +*/ + + +function App() { + const [count, setCount] = useState(0) // 0 是 count 的初始值 + const [name, setName] = useState('one') + + /* useEffect(() => { + // 定义副作用 + console.log('副作用又执行了') + document.title = count + }, []) */ // 添加一个空数组依赖项 [],组件只在首次渲染时执行一次 + + /* useEffect(() => { + // 定义副作用 + console.log('副作用又执行了') + document.title = count + }, [count]) */ // 添加特定依赖项 [count] + + // 初始化 + count 或 name 被修改时都会执行副作用函数 + useEffect(() => { + // 定义副作用 + console.log('副作用又执行了') + document.title = count + console.log(name) + }, [count,name]) + + return ( +
+ + +
+ ) +} + +export default App diff --git a/practise/31.hook/05.useState 函数作为参数.jsx b/practise/31.hook/05.useState 函数作为参数.jsx new file mode 100644 index 0000000..fb5c2c4 --- /dev/null +++ b/practise/31.hook/05.useState 函数作为参数.jsx @@ -0,0 +1,34 @@ +import { useState } from 'react' + +function getDefaultValue () { + for (let i = 0; i < 10000; i++) { + } + return '10' +} + +function Counter (props) { + const [count, setCount] = useState(() => { + /** + * 初始值经过一定的计算: + * 只要无法直接确定,需要通过一定的操作才能获取,就可以理解为计算 + */ + // return props.count + + // 循环遍历一万条数据才能确定这里的初始值 + return getDefaultValue() + }) + return ( + + ) +} + +function App () { + return ( +
+ + +
+ ) +} + +export default App \ No newline at end of file diff --git a/practise/31.hook/06.useEffect 清除副作用.jsx b/practise/31.hook/06.useEffect 清除副作用.jsx new file mode 100644 index 0000000..be2fa3b --- /dev/null +++ b/practise/31.hook/06.useEffect 清除副作用.jsx @@ -0,0 +1,30 @@ +import { useEffect, useState } from 'react' + +function Test () { + useEffect(() => { + let timer = setInterval(() => { + console.log('定时器执行了') + }, 1000) + + return () => { + // 清理定时器 + clearInterval(timer) + } + }, []) + + return ( +
this is test
+ ) +} + +function App () { + const [flag, setFlag] = useState(true) + return ( +
+ {flag ? : null} + +
+ ) +} + +export default App \ No newline at end of file diff --git a/practise/31.hook/07.useEffect 发送网络请求.jsx b/practise/31.hook/07.useEffect 发送网络请求.jsx new file mode 100644 index 0000000..0ae22bf --- /dev/null +++ b/practise/31.hook/07.useEffect 发送网络请求.jsx @@ -0,0 +1,30 @@ +/** + * 类组件发送网络请求: + * 生命周期钩子函数:componentDidMount;执行时机:在初始化的时候 dom 渲染完毕时只执行一次 + */ + +/** + * 1.不加依赖项,执行时机:初始化 + 重新渲染 + * 2.加 [] , 执行时机:初始化执行一次 + * 3.加特定的依赖项 [count, name] ,执行时机:首次执行 + 任意一个变化执行 + */ + + import { useEffect } from 'react' + + function App () { + useEffect(() => { + // 发送请求 + async function loadData () { + const res = await fetch('http://geek.itheima.net/v1_0/channels') + console.log(res) + } + loadData() + }, []) + + return ( +
+
+ ) + } + + export default App \ No newline at end of file diff --git a/practise/31.hook/08.useRef的使用.jsx b/practise/31.hook/08.useRef的使用.jsx new file mode 100644 index 0000000..169bb1c --- /dev/null +++ b/practise/31.hook/08.useRef的使用.jsx @@ -0,0 +1,45 @@ +import React, { useEffect, useRef } from 'react' + +// useRef:在函数组件中获取真实的dom元素对象或者是组件对象 +/** + * 使用步骤 + * 1. 导入 useRef 函数 + * 2. 执行 useRef 函数并传入null,返回值为一个对象 内部有一个current属性存放拿到的dom对象(类组件实例) + * 3. 通过ref 绑定 要获取的元素或者组件 + */ + +class TestC extends React.Component { + state = { + name: 'Ken' + } + + getName = () => { + return 'this is child Test' + } + + render () { + return ( +
类组件
+ ) + } +} + +function App () { + const testRef = useRef(null) + const h1Ref = useRef(null) + + // useEffect 回调是在 dom 渲染之后的。和 vue 里的 watch 效果较像,但是执行时机是不同的 + useEffect(() => { + console.log(testRef.current) + console.log(h1Ref.current) + }, []) + + return ( +
+ +

this is h1

+
+ ) +} + +export default App \ No newline at end of file diff --git a/practise/31.hook/09.useContext使用.jsx b/practise/31.hook/09.useContext使用.jsx new file mode 100644 index 0000000..64b1374 --- /dev/null +++ b/practise/31.hook/09.useContext使用.jsx @@ -0,0 +1,44 @@ +import React, { createContext, useContext, useState } from 'react' + +// 1.创建 Context 对象,调用 createContext 方法 +const Context = createContext() + +function ComA() { + const count = useContext(Context) + return ( +
+ this is ComA +
+ 传过来的数据为:{count} + +
+ ) +} + +function ComC() { + // 3.底层组件通过 useContext 函数获取数据 + const count = useContext(Context) + return ( +
+ this is ComC +
+ 传过来的数据为:{count} +
+ ) +} + +function App() { + const [ count, setCount ] = useState(0) + + return ( + // 2.顶层组件通过 Context.Provider 提供数据 + +
+ + +
+
+ ) +} + +export default App \ No newline at end of file diff --git a/practise/31.hook/hook阶段小练习/01/index.js b/practise/31.hook/hook阶段小练习/01/index.js new file mode 100644 index 0000000..b9b972f --- /dev/null +++ b/practise/31.hook/hook阶段小练习/01/index.js @@ -0,0 +1,14 @@ +import { useWindowScroll } from './useWindowScroll.js' + +function App () { + const [y] = useWindowScroll() + + return ( +
+ {y} + {console.log(y)} +
+ ) +} + +export default App \ No newline at end of file diff --git a/practise/31.hook/hook阶段小练习/01/useWindowScroll.js b/practise/31.hook/hook阶段小练习/01/useWindowScroll.js new file mode 100644 index 0000000..03cb8dd --- /dev/null +++ b/practise/31.hook/hook阶段小练习/01/useWindowScroll.js @@ -0,0 +1,13 @@ +import { useState } from 'react' + + +export function useWindowScroll () { + const [y, sety] = useState(0) + + // 在滚动行为发生的时候,不断获取滚动值,然后交给 y + window.addEventListener('scroll', () => { + const h = document.documentElement.scrollTop // documentElement 属性以一个元素对象返回一个文档的文档元素。 + sety(h) + }) + return [y] +} diff --git a/practise/31.hook/hook阶段小练习/02/index.js b/practise/31.hook/hook阶段小练习/02/index.js new file mode 100644 index 0000000..36a8c06 --- /dev/null +++ b/practise/31.hook/hook阶段小练习/02/index.js @@ -0,0 +1,15 @@ +import { useLocalStorage } from './useLocalStorage' + +function App () { + const [message, setMessage] = useLocalStorage('hook-key', 'ken') + setTimeout(() => { + setMessage('cp') + }, 5000); + return ( +
+ {message} +
+ ) +} + +export default App \ No newline at end of file diff --git a/practise/31.hook/hook阶段小练习/02/useLocalStorage.js b/practise/31.hook/hook阶段小练习/02/useLocalStorage.js new file mode 100644 index 0000000..dbf6a08 --- /dev/null +++ b/practise/31.hook/hook阶段小练习/02/useLocalStorage.js @@ -0,0 +1,15 @@ +import { useEffect, useState} from 'react' + +/* const {message, setMessage} = useState(defaultValue) +1.message 可以通过自定义传入默认初始值 +2.每次修改 message 数据的时候,都会自动往同步一份 */ + +export function useLocalStorage (key, defaultValue) { + const [message, setMessage] = useState(defaultValue) + // 每次只要 message 变化,就会自动同步到本地 localStorage + useEffect (() => { + // setItem(keyname, value) 是添加键和值,如果对应的值存在,则更新该键对应的值。 + window.localStorage.setItem(key, message) + }, [message, key]) + return [message, setMessage] +} \ No newline at end of file diff --git a/practise/31.hook/useContext/context.js b/practise/31.hook/useContext/context.js new file mode 100644 index 0000000..90c6cf7 --- /dev/null +++ b/practise/31.hook/useContext/context.js @@ -0,0 +1,13 @@ +/** + * 1.调用 createContext 方法 + * 2.通过顶层组件包裹 Context.Provider + * 3.底层组件 useContext (createContext 返回的对象) + */ + +import { createContext } from "react" + +const Context = createContext() + +export default Context + + diff --git a/practise/31.hook/useContext/index.js b/practise/31.hook/useContext/index.js new file mode 100644 index 0000000..129cfe7 --- /dev/null +++ b/practise/31.hook/useContext/index.js @@ -0,0 +1,43 @@ +import React, { useContext, useState } from 'react' + +import Context from './context' + +function ComA() { + const count = useContext(Context) + return ( +
+ this is ComA +
+ 传过来的数据为:{count} + +
+ ) +} + +function ComC() { + // 3.底层组件通过 useContext 函数获取数据 + const count = useContext(Context) + return ( +
+ this is ComC +
+ 传过来的数据为:{count} +
+ ) +} + +function App() { + const [ count, setCount ] = useState(0) + + return ( + // 2.顶层组件通过 Context.Provider 提供数据 + +
+ + +
+
+ ) +} + +export default App \ No newline at end of file diff --git a/practise/31.hook/useContext补充.png b/practise/31.hook/useContext补充.png new file mode 100644 index 0000000..c8d68c8 Binary files /dev/null and b/practise/31.hook/useContext补充.png differ diff --git a/practise/32.react-router/01.BrowserRouter.jsx b/practise/32.react-router/01.BrowserRouter.jsx new file mode 100644 index 0000000..dce7e19 --- /dev/null +++ b/practise/32.react-router/01.BrowserRouter.jsx @@ -0,0 +1,25 @@ +// 引入两个组件 +import Home from "./Home"; +import About from "./About"; + +import { BrowserRouter, Link, Routes, Route} from "react-router-dom" + +// 进行路由配置 +function App() { + return ( + // BrowserRouter 是声明当前要用一个非 hash 模式的路由 + + {/* Link 是指定跳转的组件,to 用来配置路由地址 */} + 首页 + 关于 + {/* Routes 是路由出口,路由对应的组件会在这里进行渲染 */} + + {/* Route 是指定路径和组件的对应关系,path 代表路径,element 代表组件,两个是成对出现的,一个 path 对应一个 element */} + }> + }> + + + ); +} + +export default App; diff --git a/practise/32.react-router/02.编程式导航-实现跳转/Login.js b/practise/32.react-router/02.编程式导航-实现跳转/Login.js new file mode 100644 index 0000000..0629c24 --- /dev/null +++ b/practise/32.react-router/02.编程式导航-实现跳转/Login.js @@ -0,0 +1,21 @@ +// 1.导入 useNavigate +import { useNavigate } from 'react-router-dom' + +function Login() { + // 2.执行 useNavigate 得到一个跳转函数 + const navigate = useNavigate() + + function goAbout() { + // 3.调用跳转函数传入目标路径,{replace: true} 是在跳转时不加入历史记录,不能跳转回登录页 + navigate('/about', {replace: true}) + } + + return ( +
+ Login + +
+ ) +} + +export default Login \ No newline at end of file diff --git a/practise/32.react-router/02.编程式导航-实现跳转/index.js b/practise/32.react-router/02.编程式导航-实现跳转/index.js new file mode 100644 index 0000000..17e90e1 --- /dev/null +++ b/practise/32.react-router/02.编程式导航-实现跳转/index.js @@ -0,0 +1,28 @@ +// 引入两个组件 +import Home from "./Home"; +import About from "./About"; +import Login from "./Login"; + +import { BrowserRouter, Link, Routes, Route} from "react-router-dom" + +// 进行路由配置 +function App() { + return ( + // BrowserRouter 是声明当前要用一个非 hash 模式的路由 + + {/* Link 是指定跳转的组件,to 用来配置路由地址 */} + 首页 + 关于 + {/* 登录 */} + {/* Routes 是路由出口,路由对应的组件会在这里进行渲染 */} + + {/* Route 是指定路径和组件的对应关系,path 代表路径,element 代表组件,两个是成对出现的,一个 path 对应一个 element */} + }> + }> + }> + + + ); +} + +export default App; diff --git a/practise/32.react-router/03.跳转传参-searchParams/About.js b/practise/32.react-router/03.跳转传参-searchParams/About.js new file mode 100644 index 0000000..14e47dd --- /dev/null +++ b/practise/32.react-router/03.跳转传参-searchParams/About.js @@ -0,0 +1,17 @@ +import { useSearchParams } from 'react-router-dom' + +function About () { + const [params] = useSearchParams() + + /** + * params 是一个对象,对象里有一个 get 的方法,用来获取对应的参数,把参数的名称作为 get 方法的实参传过来 + */ + + const id = params.get('id') + + return ( +
About得到的参数 id 值为 {id}
+ ) +} + +export default About \ No newline at end of file diff --git a/practise/32.react-router/03.跳转传参-searchParams/Login.js b/practise/32.react-router/03.跳转传参-searchParams/Login.js new file mode 100644 index 0000000..255828e --- /dev/null +++ b/practise/32.react-router/03.跳转传参-searchParams/Login.js @@ -0,0 +1,21 @@ +// 1.导入 useNavigate +import { useNavigate } from 'react-router-dom' + +function Login() { + // 2.执行 useNavigate 得到一个跳转函数 + const navigate = useNavigate() + + function goAbout() { + // 3.调用跳转函数传入目标路径,{replace: true} 是在跳转时不加入历史记录,不能跳转回登录页 + navigate('/about?id=1001', {replace: true}) + } + + return ( +
+ Login + +
+ ) +} + +export default Login \ No newline at end of file diff --git a/practise/32.react-router/04.跳转传参-params/About.js b/practise/32.react-router/04.跳转传参-params/About.js new file mode 100644 index 0000000..c350136 --- /dev/null +++ b/practise/32.react-router/04.跳转传参-params/About.js @@ -0,0 +1,15 @@ +// 使用 params 传参。还需要在 App.js 的传参路径 path 添加 /:id +// 例如:}> + +import { useParams } from 'react-router-dom' + +function About () { + + const params = useParams() + + return ( +
About得到的参数 id 值为 {params.id}
+ ) +} + +export default About \ No newline at end of file diff --git a/practise/32.react-router/04.跳转传参-params/Login.js b/practise/32.react-router/04.跳转传参-params/Login.js new file mode 100644 index 0000000..563eda1 --- /dev/null +++ b/practise/32.react-router/04.跳转传参-params/Login.js @@ -0,0 +1,21 @@ +// 1.导入 useNavigate +import { useNavigate } from 'react-router-dom' + +function Login() { + // 2.执行 useNavigate 得到一个跳转函数 + const navigate = useNavigate() + + function goAbout() { + // 3.调用跳转函数传入目标路径,{replace: true} 是在跳转时不加入历史记录,不能跳转回登录页 + navigate('/about/1001', {replace: true}) + } + + return ( +
+ Login + +
+ ) +} + +export default Login \ No newline at end of file diff --git a/practise/32.react-router/05.嵌套路由/Article.js b/practise/32.react-router/05.嵌套路由/Article.js new file mode 100644 index 0000000..f301f89 --- /dev/null +++ b/practise/32.react-router/05.嵌套路由/Article.js @@ -0,0 +1,7 @@ +function Article () { + return ( +
Article
+ ) +} + +export default Article \ No newline at end of file diff --git a/practise/32.react-router/05.嵌套路由/Board.js b/practise/32.react-router/05.嵌套路由/Board.js new file mode 100644 index 0000000..6d76ba6 --- /dev/null +++ b/practise/32.react-router/05.嵌套路由/Board.js @@ -0,0 +1,7 @@ +function Board () { + return ( +
Board
+ ) +} + +export default Board \ No newline at end of file diff --git a/practise/32.react-router/05.嵌套路由/Layout.js b/practise/32.react-router/05.嵌套路由/Layout.js new file mode 100644 index 0000000..9d53a12 --- /dev/null +++ b/practise/32.react-router/05.嵌套路由/Layout.js @@ -0,0 +1,12 @@ +import { Outlet } from 'react-router-dom' + +function Layout () { + return ( +
+ Layout + +
+ ) +} + +export default Layout \ No newline at end of file diff --git a/practise/32.react-router/05.嵌套路由/Login.js b/practise/32.react-router/05.嵌套路由/Login.js new file mode 100644 index 0000000..f3aaf1d --- /dev/null +++ b/practise/32.react-router/05.嵌套路由/Login.js @@ -0,0 +1,10 @@ +function Login() { + + return ( +
+ Login +
+ ) +} + +export default Login \ No newline at end of file diff --git a/practise/32.react-router/05.嵌套路由/index.js b/practise/32.react-router/05.嵌套路由/index.js new file mode 100644 index 0000000..5c42910 --- /dev/null +++ b/practise/32.react-router/05.嵌套路由/index.js @@ -0,0 +1,29 @@ +// 引入两个组件 +import Login from "./Login"; +import Layout from "./Layout"; +import Board from "./Board"; +import Article from "./Article"; + +import { BrowserRouter, Routes, Route} from "react-router-dom" + +// 进行路由配置 +function App() { + return ( + + + + + + }> + {/* 定义二级路由嵌套 */} + }> + }> + + + }> + + + ); +} + +export default App; diff --git a/practise/32.react-router/06.默认二级路由设置.jsx b/practise/32.react-router/06.默认二级路由设置.jsx new file mode 100644 index 0000000..99060af --- /dev/null +++ b/practise/32.react-router/06.默认二级路由设置.jsx @@ -0,0 +1,30 @@ +// 引入两个组件 +import Login from "./Login"; +import Layout from "./Layout"; +import Board from "./Board"; +import Article from "./Article"; + +import { BrowserRouter, Routes, Route} from "react-router-dom" + +// 进行路由配置 +function App() { + return ( + + + + + + }> + {/* 定义二级路由嵌套 */} + {/* 进入页面指定显示:默认二级,添加 index 属性,将自己的 path 干掉 */} + }> + }> + + + }> + + + ); +} + +export default App; diff --git a/practise/32.react-router/07.404页配置/NotFound.js b/practise/32.react-router/07.404页配置/NotFound.js new file mode 100644 index 0000000..aa403a3 --- /dev/null +++ b/practise/32.react-router/07.404页配置/NotFound.js @@ -0,0 +1,9 @@ +function NotFound () { + return ( +
+ sorry,this page is lost +
+ ) +} + +export default NotFound \ No newline at end of file diff --git a/practise/32.react-router/07.404页配置/index.js b/practise/32.react-router/07.404页配置/index.js new file mode 100644 index 0000000..9571eb6 --- /dev/null +++ b/practise/32.react-router/07.404页配置/index.js @@ -0,0 +1,30 @@ +// 引入两个组件 +import Layout from "./Layout"; +import Board from "./Board"; +import Article from "./Article"; +import NotFound from "./NotFound"; + +import { BrowserRouter, Routes, Route} from "react-router-dom" + +// 进行路由配置 +function App() { + return ( + + + + + + }> + {/* 定义二级路由嵌套 */} + }> + }> + + + {/* 当所有的路径都没有匹配时,做兜底匹配,显示未找到 */} + }> + + + ); +} + +export default App; diff --git a/practise/32.react-router/picture/1.png b/practise/32.react-router/picture/1.png new file mode 100644 index 0000000..27bfb94 Binary files /dev/null and b/practise/32.react-router/picture/1.png differ diff --git a/practise/32.react-router/picture/2.png b/practise/32.react-router/picture/2.png new file mode 100644 index 0000000..33a30f9 Binary files /dev/null and b/practise/32.react-router/picture/2.png differ diff --git a/practise/32.react-router/picture/3.png b/practise/32.react-router/picture/3.png new file mode 100644 index 0000000..1db86dc Binary files /dev/null and b/practise/32.react-router/picture/3.png differ diff --git a/practise/32.react-router/picture/4.png b/practise/32.react-router/picture/4.png new file mode 100644 index 0000000..8911d4d Binary files /dev/null and b/practise/32.react-router/picture/4.png differ diff --git a/practise/32.react-router/picture/5.编程式导航.png b/practise/32.react-router/picture/5.编程式导航.png new file mode 100644 index 0000000..bee4877 Binary files /dev/null and b/practise/32.react-router/picture/5.编程式导航.png differ diff --git a/practise/32.react-router/picture/6.跳转传参.png b/practise/32.react-router/picture/6.跳转传参.png new file mode 100644 index 0000000..c257fae Binary files /dev/null and b/practise/32.react-router/picture/6.跳转传参.png differ diff --git a/practise/32.react-router/picture/7.嵌套路由.png b/practise/32.react-router/picture/7.嵌套路由.png new file mode 100644 index 0000000..cbe79bb Binary files /dev/null and b/practise/32.react-router/picture/7.嵌套路由.png differ diff --git a/practise/32.react-router/picture/8.404路由配置.png b/practise/32.react-router/picture/8.404路由配置.png new file mode 100644 index 0000000..6b6d490 Binary files /dev/null and b/practise/32.react-router/picture/8.404路由配置.png differ