react JSX 语法
允许使用函数声明的方式去定义一些组件
<script type="text/bable">
function HelloReact(){
return(
<h1>Hello world</h1>
)
}
ReactDOM.render(<HellloReact/>, document.getElementById('root'));
返回值
支撑返回String type
支持HTML标签<h1>Hello</h1> 也支持嵌套 return 用()括起来
return (
<articlae>
<h1>hello</h1>
</articlae>
);
JSX返回体智能包含一个根节点root
return (
<Rect.Fragment> // JSX语法自带的 推荐的解决方案 也可以用<>空标签
<header>This is a header</header> /*header 标签和article标签冲突*/ 可以外面在嵌套一层div
<articlae>
<h1>hello</h1>
</articlae>
</Rect.Fragment>
);
组件命名(JSX)
遵循大驼峰的命名方式(所有的单词首字母都大写)Article(); (小驼峰是所有单词首字母小写)
- 可以区分原生 HTML 元素和自定义的 React 组件
- 可以区分 JS 函数(小驼峰)和 React 组件(大驼峰)
属性命名
遵循小驼峰命名方式
function sayHello () {
alert('hell0');
}
return (
<button className="button">button</button> //class的属性命名要变成 className
<button onClick={sayHello}></button> //onclick 要变成onClick 后面跟的是个对象不能是String,内部是个function
)
样式处理
同样用style来传递样式,但是style={{}}要求传递是一个对象
// 小驼峰命名
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}
// 同样的形式 推荐这样写法
const buttonStyle = {
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}
sytle={buttonStyle}
表达式变量
function HomePage() {
const name = "Yafei";
return (<h1>Hello, {name}!</h1>); // 直接定义变量,在返回值中直接使用变量
}
ReactDOM.render(
<HomePage />
, document.getElementById('root'));
表达式函数
function HomePage() {
const name = "Yafei";
const getCurrentTime = () => {
return (new Date()).toLocaleTimeString(); // 函数内部还可以定义函数 也可以直接使用函数
}
return (
<React.Fragment>
<h1>Hello,{name}!</h1>
<p>Current time is: {getCurrentTime()}</p>
</React.Fragment>
); // 直接定义变量,在返回值中直接使用变量
}
ReactDOM.render(
<HomePage />
, document.getElementById('root'));
花括号{}
{} 可以任意的调用变量name, 对象, 函数。
function DynamicButton() {
const [isActive, setIsActive] = React.useState(false);
return (
// 自由嵌套表达式
<div className={isActive ? "active" : "inactive"}>
This is an {isActive ? "active" : "inactive"} component.
<button onClick={() => setIsActive(!isActive)}>
change to {isActive ? "inactive" : "active"}
</button>
</div>
);
}条件渲染
三元运算符 和 逻辑运算符
三元运算符就是if else, 逻辑与运算符只判断一个情况时出现时,处理后续逻辑
function UserStatus() {
const name = 'user';
const [isLogin, setIsLogin] = React.useState(fales);
return (
<div> // 三元运算符判断
{isLogin ? <p>{name}, Welcome back!</p> : <P>Please log in.</P>}
<button onClick={() => setIsLogin(!isLogin)}>change user status</button>
</div>
);
}
function WarningMsg() {
const [visiblem, setVisible] = React.userState(false); // 初始化 fales
return (
<div> // &&逻辑与运算符 当visible是true时,显示信息
{visible && <p className="warning">This is a warning messages</p>}
<button onClick={() => setVisible(!visible)}>change visible</button>
</div>
);
}
列表渲染
function TodoList() {
const tods = [
{ text: "Learn react"},
{ text: "Learn react"},
{ text: "Learn react"},
{ text: "Learn react"}
];
// 批量渲染数据就使用map方法
// 需要注意:使用 Array.map 方法批量渲染的时候
// 需要给每一个渲染的根节点传入一个唯一的 key 属性
return (
<ul>
{tods.map((todo, index) => (
<li key={index}>
<span style={{ color: 'green' }}>{todp.text}</span>
</li>
))}
</ul>
);
}
React组件
函数式组件
函数式组件定义和 JavaScript 普通的函数定义相同
但是它内部遵循的语法是 JSX语法定义的名称
通常用大驼峰return
返回体是只有一个根节点的 JSX 模板
function HelloReact() {
const name = "myName";
const greet = () => {
alert(`Hello my name's: ${name}`);
};
return (
<div>
<h1>Hello React</h1>
<button onClick={greet}>Say hello</button>
</div>
)
};
ReactDOM.render(<HellReact />, document.getElementById("root"));
组件化思想
将功能拆开 Header Main Footer分开来写,分成组件来写
function App(){
return (
<>
<Header />
<Main />
<Footer />
</>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
组件State
State就是管理组件内部的状态集合,必须使用react内部提供的方式去修改内部状态
function Counter() {
// userState 是内部状态 传入了初始值0,内部状态就是count count初始值是0,
// setCount 是改变内部状态的方法 能改变count值的
const [count, setCount] = React.userState(0);
return(
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Clikc me</button>
// 下面这样写会报错
<button onClick={() => count =count + 1}>Clikc</button> ×
</div>
)
}
组件Props
Props能接收外面传过来值
function HelloButton(props) {
// props 能接受多个参数 such as {name, age, email} = props;
const {name} = props;
const greet = () => {
alert(`hello: ${name}`);
}
return <button onClick={greet}>hello</button>
}
function HelloPerson() {
// 维护了一个State,命名为Name
const [name, setName] = React.useState("");
const onNameChange = (e) => {
setName(e.target.value);
};
return (
<div>
<input onChange={onNameChange} />
<HelloButton name={name} />
</div>
)
}
React事件处理
鼠标Event
- onClick() 点击
- onMouseEnter() 鼠标移入
- onMouseLeave() 鼠标移出
- onDoubleClick() 双击
- onMouseMove() 鼠标移动
- onMouseDown() 左键按下
- onMouseUp() 左键松开
键盘Event
function Input(props) {
const handleKeyPress = (event) => {
console.log("Key Pressed:", event.key);
};
return (
<input type="text" onKeyPress={handleKeyPress} />
);
}
ReactDOM.render(<Input />, document.getElementById("root"));
监听到按下的是哪个字母
- onKeyPress
- onKeyUp
- onKeyDown
表单Event
function Form(props) {
const handleChange = (event) => {
console.log("当前输入值是:", event.target.value);
};
const hadleFocus = () => {
console.log("input 获取焦点");
};
const handleBlur = () => {
console.log("input 失去焦点");
};
const handleLikeChange = () => {
const { chechked } = event.target;
console.log('like frontend', checked);
};
return (
<form>
<input
type="text"
onChange={handleChange}
onFocus={hadleFocus}
onBlur={handleBlur}
/>
<br />
<input type="checkbox" onCHange={handleLikeChange} />Like Frontend
</form>
)
}
- onChange
- onBlur
- onFocus
事件命名规范
用语义来命名相关的处理事件的函数: handleCheckBoxChange, onCheckBoxChange,handleBlur
工程化
初始化项目
Vite 初始化项目 https://vite.dev/ 查看官方文档
导入导出
导出
// 写法一
function Comp() {
return <h1>Hellp</h1>
}
export default Comp;
// 写法二
export default function Comp() {
return <h1>Hellp</h1>
}
导入
import Comp from '../'
// 具名导出可以导出多个
import { CompName } from '../'
什么是useEffect()?
useEffect 是 React 提供的一个 副作用钩子(Side Effect Hook),用于在函数组件中执行“额外操作”,比如:
- 向后端请求数据
- 手动修改 DOM(比如动画)
- 设置定时器、监听事件
- 本地存储或清除缓存
✅ 基本结构:
useEffect(() => {
// 执行副作用
}, [依赖]);
// (依赖更新时执行(比如监听 score 变化))
useEffect(() => {
localStorage.setItem("score", score);
}, [score]);
如果不传 [],每次组件重新渲染都会执行一次如果传 [someVar],只有 someVar 改变时才执行
全局的状态管理
在不同路由下相互传递数据,React 默认通过props 一层层传数据(叫 prop drilling),但当组件结构很深时会很麻烦。 因此React提供了createContext() 提供了解决方案:createContext() 提供了解决方案:
创建一个“全局仓库”,任何组件都可以从中“读/写”数据,不需要层层传递 props
// 一般默认导入需要这几个方法
import React, { createContext, useContext, useState, useEffect } from 'react'
const ScoreContext = createContext(); // 创建一个全局上下文对象,这个对象本身没数据,只是个“载体”。
export const useScore = () => useContext(ScoreContext); //我想访问 ScoreContext 提供的全局数据和方法
<ScoreContext.Provider value={...}> // 在返回时必须要写的内容,ScoreContext就是刚刚创建的全局上下文object
✅ 示例:
import React, { createContext, useContext, useState, useEffect } from 'react'
const ScoreContext = createContext();
// “这里意思是我想访问 ScoreContext 提供的全局数据和方法”
export const useScore = () => useContext(ScoreContext);
// ScoreProvider 里面的必须要写{children}
export default function ScoreProvider({ children }) {
const [score, setScore] = useState(0);
useEffect(() => {
const storedScore = localStorage.getItem('score');
if (storedScore !== null) {
setScore(Number(storedScore));
} else {
fetchInitScore(setScore);
}
}, []);
const upScore = () => {
setScore(prev => {
const updated = prev + 1;
localStorage.setItem('score', updated);
return updated;
});
};
const resetScore = () => {
setScore(preve => {
const preve = 0;
localStorage.setItem('score', preve);
return preve;
})
};
return (
<ScoreContext.Provider value={{ score, setScore, upScore, resetScore }}>
{children}
// {/* 显式插入你包住的内容 */}
</ScoreContext.Provider>
);
}
在别的组件中调用就这样使用
import { useScore } from "./ScoreContext";
const { score, upScore } = useScore();
const { score, upScore } = useScore(); 中的
score和upScore,必须是你在 <ScoreContext.Provider value={…}> 中定义并传进去的变量或函数。❌ 如果你尝试拿不存在的内容:const { nonExistent } = useScore(); // ❌ value 中没有这个字段 就会报错
发表回复
要发表评论,您必须先登录。