代码拉取完成,页面将自动刷新
//项目的根组件
//App-->index.js-->public/index.html(root)
const count = 100
function getName() {
return 'jack'
}
function App() {
return (
<div className="App">
this is App
{/* 使用引号传递字符串 */}
{'this is message'}
{/* 识别js变量 */}
{count}
{/* 函数调用 */}
{getName()}
{/* 方法调用 */}
{new Date().getDate()}
{/* 使用js对象 */}
<div style={{ color: 'red' }}>this is div</div>
</div>
);
}
export default App;
//项目的根组件
//App-->index.js-->public/index.html(root)
const list = [
{ id: 1001, name: 'Vue' },
{ id: 1002, name: 'React' },
{ id: 1003, name: 'Angular' },
]
function App() {
return (
<div className="App">
this is App
{/* 渲染列表 */}
{/* map循环那个结构 return那个结构 */}
{/* 注意事项:加上独一无二的key 字符串或number*/}
{/* key的作用:React框架内部使用 提升更新性能 */}
<ul>
{list.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
</div>
);
}
export default App;
//项目的根组件
//App-->index.js-->public/index.html(root)
const isLogin = true
function App() {
return (
<div className="App">
{/* 逻辑与&& */}
{isLogin && <span>this is span</span>}
{/* 三元运算 */}
{isLogin?<span>jack</span>:<span>loading ....</span>}
</div>
);
}
export default App;
//项目的根组件
//App-->index.js-->public/index.html(root)
//定义文章类型
const articleType = 3 //0 1 3
//定义核心函数(根据文章类型返回不同的jsx模板)
function getArticleTem() {
if (articleType === 0) {
return <div>我是无图文章</div>
} else if (articleType === 1) {
return <div>我是单图模式</div>
} else {
return <div>我是三图模式</div>
}
}
function App() {
return (
<div className="App">
{/* 通过调用函数渲染不同的模板 */}
{getArticleTem()}
</div>
);
}
export default App;
//项目的根组件
//App-->index.js-->public/index.html(root)
function App() {
// 基础绑定
// const handleClick = () => {
// console.log("button 被点击了");
// }
//事件参数e
// const handleClick = (e) => {
// console.log("button 被点击了", e);
// }
//传递自定义参数
// const handleClick = (name) => {
// console.log("button 被点击了", name);
// }
//既要传递自定义参数 而且还要事件对象e
const handleClick = (name, e) => {
console.log("button 被点击了", name, e);
}
return (
<div className="App">
{/* <button onClick={handleClick}>click me</button> */}
{/* 传递自定义参数 */}
{/* <button onClick={() => handleClick('jack')}>click me</button> */}
{/* 既要传递自定义参数 而且还要事件对象e */}
<button onClick={(e) => handleClick('jack', e)}>click me</button>
</div>
);
}
export default App;
//1.定义组件
//第一种方式
// function Button(){
// //业务逻辑 组件逻辑
// return <button>click me!</button>
// }
//第二种方式
const Button = () => {
//业务逻辑 组件逻辑
return <button>click me!</button>
}
function App() {
return (
<div className="App">
{/* 2.使用组件 {渲染组件} */}
{/* 自闭和 */}
<Button />
{/* 成对标签 */}
<Button></Button>
</div>
);
}
export default App;
//userState实现一个计数器按钮
import { useState } from "react";
function App() {
//1.调用useState添加一个状态变量
//count 状态变量
// setCount 修改状态变量的方法
const [count, setCount] = useState(0)
//2.点击事件回调
const handleClick = () => {
//作用: 1.用传入的新值修改count
//2.重新使用新的count渲染UI
setCount(count + 1)
}
return (
<div className="App">
<button onClick={handleClick}>{count}</button>
</div>
);
}
export default App;
import { useState } from "react";
function App() {
const [count, setCount] = useState(0)
const handleClick = () => {
//直接修改 无法引起视图更新
// count++
// console.log(count)
setCount(count + 1)
}
//修改对象状态
const [form, setForm] = useState({ name: 'jack' })
const changeForm = () => {
//错误写法:直接修改
// form.name='john'
// 正确写法:setFrom 传入一个全新的对象
setForm({
...form,
name: 'john'
})
}
return (
<div className="App">
<button onClick={handleClick}>{count}</button>
<button onClick={changeForm}>修改form{form.name}</button>
</div>
);
}
export default App;
//导入样式
import './index.css'
const style={
color:'red',
fontSize:'50px'
}
function App() {
return (
<div className="App">
{/* 行内样式控制 */}
{/* <span style={{ color: 'red', fontSize: '50px' }}>this is span</span> */}
<span style={style}>this is span</span>
{/* 通过class类名控制 */}
<span className="foo">this is class foo</span>
</div>
);
}
export default App;
.foo{
color: blue;
}
import { useState } from 'react'
//受控绑定表单
//1.声明一个react状态 - useState
//2.核心绑定流程
//1.通过value属性绑定react状态
//2.绑定onChange事件 通过事件参数e拿到输入框最新的值 反向修改到react状态身上
function App() {
const [value, setValue] = useState('')
return (
<div>
<input type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
</div>
);
}
export default App;
import { useRef, useState } from 'react'
//React获取DOM
//1.useRef生成ref对象 绑定到dom标签身上
//2.dom可用时,ref.current获取dom
//渲染完毕后dom生成之后才可用
function App() {
const inputRef = useRef(null)
const showDom=()=>{
console.dir(inputRef.current)
}
return (
<div>
<input type="text" ref={inputRef}/>
<button onClick={showDom}>获取dom</button>
</div>
);
}
export default App;
//父传子
//1.父组件传递数据 子组件标签身上绑定属性
//2.子组件接收数据 props的参数
function Son(props) {
// props:对象里面包含了父组件传递过来的所有数据
// {name:'父组件中的数据'}
console.log(props);
return <div>{props.name}</div>
}
function App() {
const name = 'this is app name'
return (
<div>
<Son name={name}></Son>
</div>
);
}
export default App;
//父传子
//1.父组件传递数据 子组件标签身上绑定属性
//2.子组件接收数据 props的参数
function Son(props) {
// props:对象里面包含了父组件传递过来的所有数据
// {name:'父组件中的数据'}
console.log(props);
// 不允许直接修改父组件传递过来的数据
// props.name='new name'
return <div>{props.name},jsx{props.child}:</div>
}
function App() {
const name = 'this is app name'
return (
<div>
<Son
name={name}
age={18}
isTrue={false}
list={['vue', 'react']}
obj={{ name: 'jack' }}
cb={() => console.log(123)}
child={<span>this is span</span>}
></Son>
</div>
);
}
export default App;
function Son(props) {
console.log(props)
return <div>this is son {props.children}</div>
}
function App() {
return (
<div>
<Son>
<span>this is apan</span>
</Son>
</div>
);
}
export default App;
//核心:在子组件中调用父组件中的函数并传递实参
import { useState } from 'react'
function Son({ onGetSonMsg }) {
//Son组件中的数据
const sonMsg = 'this is son msg'
return (
<div>
this is son
<button onClick={() => onGetSonMsg(sonMsg)}>sendMsg</button>
</div>
)
}
function App() {
const [msg, setMsg] = useState('')
const getMsg = (msg) => {
console.log(msg)
setMsg(msg)
}
return (
<div>
this is app,{msg}
<Son onGetSonMsg={getMsg} />
</div>
);
}
export default App;
//1.通过子传父A->App
//2.通过父传子 App->B
import { useState } from 'react'
function A({ onGetName }) {
//Son组件中的数据
const name = 'this is A name'
return (
<div>
this is A compenet
<button onClick={() => onGetName(name)}>send</button>
</div>
)
}
function B({name}) {
return (
<div>
this is B compenet
{name}
</div>
)
}
function App() {
const [name, setName] = useState('')
const getAname = (name) => {
console.log(name)
setName(name)
}
return (
<div>
this is app
<A onGetName={getAname} />
<B name={name}/>
</div>
);
}
export default App;
//1.createContext方法创建一个上下文对象
//2.在顶层组件 通过Provider组件提供数据
//3.在底层组件 通过useContext钩子函数使用数据
import { createContext, useContext } from 'react'
const MsgContext = createContext()
function A() {
return (
<div>
this is A compenet
<B />
</div>
)
}
function B() {
const msg= useContext(MsgContext)
return (
<div>
this is B compenet,{msg}
</div>
)
}
function App() {
const msg = 'this is app msg'
return (
<div>
<MsgContext.Provider value={msg}>
this is app
<A />
</MsgContext.Provider>
</div>
);
}
export default App;
import { useState } from "react";
import { useEffect } from "react";
const URL='http://geek.itheima.net/v1_0/channels'
function App() {
//创建一个状态
const [list,setList]=useState([])
useEffect(()=>{
//额外的操作 获取频道列表
async function getList(){
const res= await fetch(URL)
const list=await res.json()
console.log(list);
setList(list.data.channels)
}
getList()
},[])
return (
<div>
this is app
<ul>
{list.map(item=><li key={item.id}>{item.name}</li>)}
</ul>
</div>
);
}
export default App;
import { useState } from "react";
import { useEffect } from "react";
function App() {
//1.没有依赖项 初始 + 组件更新
const [count,setCount]=useState(0)
// useEffect(()=>{
// console.log('副作用函数执行了')
// })
//2.传入空数组依赖 初始渲染时执行一次
// useEffect(()=>{
// console.log('副作用函数执行了')
// },[])
//3.传入特定依赖项 初始+依赖项变化时执行(像watch)
useEffect(()=>{
console.log('副作用函数执行了')
},[count])
return (
<div>
this is app
<button onClick={()=>setCount(count+1)}>+{count}</button>
</div>
);
}
export default App;
import { useState } from "react";
import { useEffect } from "react";
function Son(){
//1.渲染时开启定时器
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>
);
}
export default App;
//封装自定义hook
//问题:布尔切换的逻辑 当前组件耦合在一起 不方便复用
//解决思路:自定义hook
import { useState } from 'react';
function useToggle() {
//可复用的逻辑代码
const [value, setValue] = useState(true);
const toggle = () => setValue(!value);
//哪些状态和回调函数需要在其他组件中使用 return
return {
value,
toggle,
};
}
//封装自定义hook通用思路
//1.声明一个以use打头的函数
//2.在函数体内封装可复用逻辑(只要是可复用的逻辑)
//3.把组件中用到的状态或者回调retutn出去(以对象或者数组)
//4.在那个组件中要用到这个逻辑,就执行这个函数,解构出状态和回调进行使用
function App() {
//通过条件渲染模拟组件卸载
// const [value, setValue] = useState(true);
// const toggle = () => setValue(!value);
const { value, toggle } = useToggle();
return (
<div>
{value && <div>this is div</div>}
<button onClick={toggle}>toggle</button>
</div>
);
}
export default App;
使用规则
只能在组件中或者其他自定义Hook函数中调用
只能在组件的顶层调用,不能嵌套在 if、for、其他函数中
import { useState } from "react";
//1.组件外使用
// useState('')
function App() {
if(Math.random()>0.5){
//2.if for 组件内部函数
// useState()
}
return (
<div>
this is app
</div>
);
}
export default App;
<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button>
<script src="https://unpkg.com/browse/redux@3.1.0/dist/redux.min.js"></script>
<script>
// 1. 定义reducer函数
// 作用: 根据不同的action对象,返回不同的新的state
// state: 管理的数据初始状态
// action: 对象 type 标记当前想要做什么样的修改
function reducer (state = { count: 0 }, action) {
// 数据不可变:基于原始状态生成一个新的状态
if (action.type === 'INCREMENT') {
return { count: state.count + 1 }
}
if (action.type === 'DECREMENT') {
return { count: state.count - 1 }
}
return state
}
// 2. 使用reducer函数生成store实例
const store = Redux.createStore(reducer)
// 3. 通过store实例的subscribe订阅数据变化
// 回调函数可以在每次state发生变化的时候自动执行
store.subscribe(() => {
console.log('state变化了', store.getState())
document.getElementById('count').innerText = store.getState().count
})
// 4. 通过store实例的dispatch函数提交action更改状态
const inBtn = document.getElementById('increment')
inBtn.addEventListener('click', () => {
// 增
store.dispatch({
type: 'INCREMENT'
})
})
const dBtn = document.getElementById('decrement')
dBtn.addEventListener('click', () => {
// 减
store.dispatch({
type: 'DECREMENT'
})
})
// 5. 通过store实例的getState方法获取最新状态更新到视图中
</script>
配置基础环境
1. 使用 CRA 快速创建 React 项目
npx create-react-app react-redux
2. 安装配套工具
npm i @reduxjs/toolkit react-redux
3. 启动项目
npm run start
store目录结构与
counterStore.js
import {createSlice} from '@reduxjs/toolkit'
const counterStore= createSlice({
name:'counter',
//初始化state
initialState:{
count:0
},
//修改数据方法,同步方法 支持直接修改
reducers:{
inscrement(state){
state.count++
},
decrement(state){
state.count--
}
}
})
//结构出来actionCreater函数
const {inscrement,decrement}= counterStore.actions
//获取reducer
const reducer=counterStore.reducer
//以按需导出的方式导出结构出来actionCreater
export {inscrement,decrement}
//以默认导出的方式导出reducer
export default reducer
store-->index.js
import { configureStore } from "@reduxjs/toolkit";
//导入子模块reducer
import counterReducer from './modules/counterStore'
const store= configureStore({
reducer:{
counter:counterReducer
}
})
export default store
src-->index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
//导入根store
import store from './store';
import { Provider } from 'react-redux';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
{/* 注入store */}
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
App使用store进行增减操作
import {useDispatch, useSelector} from 'react-redux'
//导入actionCreater
import {inscrement,decrement} from './store/modules/counterStore'
function App() {
const {count}=useSelector(state=>state.counter)
const dispatch=useDispatch()
return (
<div className="App">
<button onClick={()=>dispatch(decrement())}>-</button>
{count}
<button onClick={()=>dispatch(inscrement())}>+</button>
</div>
);
}
export default App;
counterStore.js
import {createSlice} from '@reduxjs/toolkit'
const counterStore= createSlice({
name:'counter',
//初始化state
initialState:{
count:0
},
//修改数据方法,同步方法 支持直接修改
reducers:{
inscrement(state){
state.count++
},
decrement(state){
state.count--
},
addToNumber(state,action){//传参部分
state.count=action.payload
}
}
})
//结构出来actionCreater函数
const {inscrement,decrement,addToNumber}= counterStore.actions
//获取reducer
const reducer=counterStore.reducer
//以按需导出的方式导出结构出来actionCreater
export {inscrement,decrement,addToNumber}
//以默认导出的方式导出reducer
export default reducer
App.js
import {useDispatch, useSelector} from 'react-redux'
//导入actionCreater
import {inscrement,decrement,addToNumber} from './store/modules/counterStore'
function App() {
const {count}=useSelector(state=>state.counter)
const dispatch=useDispatch()
return (
<div className="App">
<button onClick={()=>dispatch(decrement())}>-</button>
{count}
<button onClick={()=>dispatch(inscrement())}>+</button>
<button onClick={()=>dispatch(addToNumber(10))}>add To 10</button>
<button onClick={()=>dispatch(addToNumber(20))}>add To 20</button>
</div>
);
}
export default App;
channelStore.js
import { createSlice } from '@reduxjs/toolkit';
import axios from 'axios';
const channelStore = createSlice({
name: 'channel',
initialState: {
channelList: [],
},
reducers: {
setChannels(state, action) {
state.channelList = action.payload;
},
},
});
//异步请求部分
const { setChannels } = channelStore.actions;
const fetchChannelList = () => {
return async (dispatch) => {
const res = await axios.get('http://geek.itheima.net/v1_0/channels');
dispatch(setChannels(res.data.data.channels));
};
};
export {fetchChannelList}
const reducer = channelStore.reducer
export default reducer
store--->index
import { configureStore } from "@reduxjs/toolkit";
//导入子模块reducer
import counterReducer from './modules/counterStore'
import channelReducer from './modules/channelStore'
const store= configureStore({
reducer:{
counter:counterReducer,
channel:channelReducer
}
})
export default store
App使用
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
//导入actionCreater
import {
inscrement,
decrement,
addToNumber,
} from './store/modules/counterStore';
import { fetchChannelList } from './store/modules/channelStore';
function App() {
const { count } = useSelector((state) => state.counter);
const { channelList } = useSelector((state) => state.channel);
const dispatch = useDispatch();
//使用useEffect触发异步请求执行
useEffect(() => {
dispatch(fetchChannelList());
}, [dispatch]);
return (
<div className="App">
<button onClick={() => dispatch(decrement())}>-</button>
{count}
<button onClick={() => dispatch(inscrement())}>+</button>
<button onClick={() => dispatch(addToNumber(10))}>add To 10</button>
<button onClick={() => dispatch(addToNumber(20))}>add To 20</button>
<ul>
{channelList.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
export default App;
npx create-react-app react-router-pro
npm i
npm i react-router-dom
npm run start
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import reportWebVitals from './reportWebVitals';
import {createBrowserRouter,RouterProvider} from 'react-router-dom'
//1.创建router实例对象并且配置路由对应关系
const router = createBrowserRouter([
{
path:'/login',
element:<div>我是登录</div>
},
{
path:'/article',
element:<div>我是文章页</div>
},
])
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<RouterProvider router={router}></RouterProvider>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
目录结构
article
const Article=()=>{
return <div>我是文章</div>
}
export default Article
login
const Login=()=>{
return <div>我是登录</div>
}
export default Login
router
import Login from '../page/Login'
import Article from '../page/Article'
import {createBrowserRouter} from 'react-router-dom'
const router = createBrowserRouter([
{
path:'/login',
element:<Login></Login>
},
{
path:'/article',
element:<Article></Article>
}
])
export default router
index
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import reportWebVitals from './reportWebVitals';
import {RouterProvider} from 'react-router-dom'
//1.导入路由router
import router from './router';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
{/* 2.路由绑定 */}
<RouterProvider router={router}></RouterProvider>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
import { Link, useNavigate } from 'react-router-dom';
const Login = () => {
const navigate = useNavigate();
return (
<div>
我是登录
{/* 声明式写法 */}
<Link to="/article">跳转到文章页</Link>
{/* 命令式的写法 */}
<button onClick={() => navigate('/article')}>跳转到文章页</button>
</div>
);
};
export default Login;
login
import { Link, useNavigate } from 'react-router-dom';
const Login = () => {
const navigate = useNavigate();
return (
<div>
我是登录
{/* 声明式写法 */}
<Link to="/article">跳转到文章页</Link>
{/* 命令式的写法 */}
<button onClick={() => navigate('/article')}>跳转到文章页</button>
<button onClick={() => navigate('/article?id=1001&name=jack')}>searchParams传参</button>
<button onClick={() => navigate('/article/1001/jack')}>Params传参</button>
</div>
);
};
export default Login;
router
import Login from '../page/Login'
import Article from '../page/Article'
import {createBrowserRouter} from 'react-router-dom'
const router = createBrowserRouter([
{
path:'/login',
element:<Login></Login>
},
{
path:'/article/:id/:name',
element:<Article></Article>
}
])
export default router
article
import { useParams, useSearchParams } from "react-router-dom"
const Article=()=>{
// const [params] = useSearchParams()
// const id= params.get('id')
// const name= params.get('name')
const params= useParams()
const id=params.id
const name=params.name
return <div>我是文章{id}-{name}</div>
// return <div>我是文章{id}</div>
}
export default Article
layout
import { Link, Outlet } from 'react-router-dom';
const Layout = () => {
return (
<div>
我是一级路由layout
<Link to="/board">面板</Link>
<Link to="/about">关于</Link>
{/* 配置二级路由出口*/}
<Outlet></Outlet>
</div>
);
};
export default Layout;
board
const Board = () => {
return <div>我是面板</div>;
};
export default Board;
about
const About = () => {
return <div>我是关于页</div>;
};
export default About;
router
import Login from '../page/Login'
import Article from '../page/Article'
import Layout from '../page/Layout'
import Board from '../page/Board'
import About from '../page/About'
import {createBrowserRouter} from 'react-router-dom'
const router = createBrowserRouter([
{
path:'/',
element:<Layout/>,
children:[
{
path:'board',
element:<Board/>
},
{
path:'about',
element:<About/>
}
]
},
{
path:'/login',
element:<Login></Login>
},
{
path:'/article/:id/:name',
element:<Article></Article>
}
])
export default router
router
import Login from '../page/Login'
import Article from '../page/Article'
import Layout from '../page/Layout'
import Board from '../page/Board'
import About from '../page/About'
import {createBrowserRouter} from 'react-router-dom'
const router = createBrowserRouter([
{
path:'/',
element:<Layout/>,
children:[
//设置为默认二级路由 一路由访问的时候,也能得到渲染
{
index:true,
element:<Board/>
},
{
path:'about',
element:<About/>
}
]
},
{
path:'/login',
element:<Login></Login>
},
{
path:'/article/:id/:name',
element:<Article></Article>
}
])
export default router
layout
import { Link, Outlet } from 'react-router-dom';
const Layout = () => {
return (
<div>
我是一级路由layout
<Link to="/">面板</Link>
<Link to="/about">关于</Link>
{/* 配置二级路由出口*/}
<Outlet></Outlet>
</div>
);
};
export default Layout;
notfound
const NotFound =()=>{
return <div>页面跑到月球了</div>
}
export default NotFound
router
import Login from '../page/Login'
import Article from '../page/Article'
import Layout from '../page/Layout'
import Board from '../page/Board'
import About from '../page/About'
import NotFound from '../page/NotFound'
import {createBrowserRouter} from 'react-router-dom'
const router = createBrowserRouter([
{
path:'*',
element:<NotFound/>
},
{
path:'/',
element:<Layout/>,
children:[
//设置为默认二级路由 一路由访问的时候,也能得到渲染
{
index:true,
element:<Board/>
},
{
path:'about',
element:<About/>
}
]
},
{
path:'/login',
element:<Login></Login>
},
{
path:'/article/:id/:name',
element:<Article></Article>
}
])
export default router
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。