class属性要写成className
<div className="box">内容</div>
事件名要驼峰式命名
比如HTML中的
onclick,在JSX中要写成onClick;onchange写成onChange:
组件的 函数名**必须首字母大写,**普通标签小写
function Welcome() {
return <h1>欢迎学习React组件化!</h1>;
}
父组件给子组件传值props
function App() {
const userInfo = {
title: "个人信息",
content: "姓名:小明,年龄:20"
};
return (
<div>
{/* 传递第1组数据:直接写死值 */}
<Childtitle="课程介绍" content="React 入门到精通" />
{/* 传递第2组数据:用变量(从对象中取) */}
<Child title={userInfo.title} content={userInfo.content}/>
{/* 传递第3组数据:简单文本 */}
<Child title="公告通知" content="明天放假" />
</div>
);
}
如果传递的值是变量、数字、布尔值等 ,必须用
{}包裹(如price={10})传值和普通函数的区别
普通函数接受参数是props,传递的参数只能是一个参数;
react传递props,使用key=value直接写在组件名上,传递多个参数;
子组件渲染
每个子组件必须加 key 属性(值要唯一),帮助 React 高效更新
{items.map((item, index) => (
<DemoItem
key={index} // 列表渲染必须加 key,唯一标识
name={item.name}
value={item.value}
/>
))}
子组件接受props可以按需解构赋值
全赋值
function Button(props) {
return (
<button style={{ backgroundColor: props.color}}>
{props.text}
</button>
);
}
解构赋值
function Button({ text, color }) {
return (
<button style={{ backgroundColor: color}} >
{text}
</button>
);
}
子组件传值父组件
使用回调函数
// 子组件:输入框
function InputBox({ onInputChange }) {
const handleChange = (e) => {
// 子组件拿到输入值,调用父组件传递的回调函数
onInputChange(e.target.value);
};
return <input type="text" onChange={handleChange} />;
}
// 父组件:接收子组件的数据
function App() {
const [text, setText] = useState("");
// 定义回调函数,接收子组件传递的数据
const handleInput = (value) => {
setText(value); // 更新父组件的状态
};
return (
<div>
<InputBox onInputChange={handleInput} />
<p>你输入了:{text}</p>
</div>
);
}
useState
惰性初始值
const initState = doSomething(() => { /* do some thing here*/});
const [state,useState] = useState(initState );
如果initState只组要计算一次,这个地方,每次render 都会调用,导致出错
// 这样初始值就只会被计算一次了
const [state,useState] = useState(() => doSomething(() => { /* do some thing here*/}););
"函数形式"的更新器, (state的异步性,如果直接使用,不会变化)
const handleAddTwo = () => {
// 函数形式:prevCount是上一次的状态
setCount(prev => prev + 1);
setCount(prev => prev + 1);
};
state记录组件内部值,props是父组传递的值,子组件不可修改
类组件中使用 State
类组件中使用 State 的方式稍复杂,
需要通过 this.state 定义状态,用 this.setState 更新状态。
import React from 'react';
class 组件名 extends React.Component {
// 1. 初始化 State(两种方式)
// 方式一:在构造函数中初始化(传统写法)
constructor(props) {
super(props);
this.state = { 状态名: 初始值 };
// 绑定到到this后使用
this.方法名1= this.方法名1.bind(this);
}
// 方式二:直接在类中初始化(简洁写法,推荐)
state = { 状态名: 初始值 };
// 2. 定义更新状态的方法(通常用箭头函数绑定 this)
方法名1 {
this.setState({ 状态名: 新值 });
};
//箭头函数,不需要绑定this
方法名2 = () => {
this.setState({ 状态名: 新值 });
};
// 3. 渲染时使用 this.state.状态名
render() {
return (
<div>
<p>{this.state.状态名}</p>
<button onClick={this.方法名1} >修改1</button>
<button onClick={this.方法名} >修改2</button>
</div>
);
}
}
类组件学习,可以参考 React基础入门------类组件讲解
事件处理
传递函数名,不带括号
<button onClick={handleClick}>点击弹窗</button>
下面是错误的
<button onClick={handleClick()}>点击弹窗</button>
类组件的中函数需要this绑定或者使用箭头函数(箭头函数没有绑定自己的this)才可以被调用
import React from 'react';
class Demo extends React.Component {
constructor(props) {
super(props);
// 在构造函数中绑定this(关键!)
this.handleClick = this.handleClick.bind(this);
}
// 类的方法
handleClick() {
alert('类组件按钮被点击了!');
}
render() {
return (
<button onClick={this.handleClick }>点击弹窗</button>
);
}
}
或者
class Demo extends React.Component {
// 箭头函数形式的方法,this指向当前组件实例
handleClick = () => {
alert('类组件按钮被点击了!');
};
render() {
return (
<button onClick={this.handleClick }>点击弹窗</button>
);
}
}
推荐函数组件,无需担心this问题
事件对象获取信息
const handleClick = (e) => {
// e.target是触发事件的按钮元素
alert(`你点击了:${e.target.innerText}`);
};
e.target指向触发事件的DOM元素,通过它可以获取元素的属性或值。
阻止默认行为:e.preventDefault()
不能使用return false;(比如链接跳转、表单提交)
事件处理函数传递参数
通过"箭头函数包裹"的方式传递参数
<button onClick={() => handleDelete(item.id)}> text </button>
箭头函数,初始化不会被执行
如果直接写
onClick={handleDelete(todo.id)},会导致组件渲染时就执行函数同时传递参数和事件对象
const handleDelete = (id, e) => {
console.log('删除的id:', id);
console.log('事件对象:', e);
};
// 调用时先传自定义参数,再传e
<button onClick={(e) => handleDelete(item.id, e)}>text</button>
状态管理
复杂的有点晦涩难懂,后期有时间再来学习,暂时先不关注;
Context+useReducer
Redux Toolkit(中大型项目首选)
Zustand和Jotai
先理解一个简单的使用Context API来管理跨层级使用数据
// 1. 创建Context
const UserContext = React.createContext();// 2.在顶层组件:用Provider提供数据
function Grandpa() {
const user = { name: '老王' };
return (
<UserContext.Provider value={user}>
<Father />
</UserContext.Provider>
);
}
// 3.深层组件:用useContext接收数据
function Grandson() {
const user = React.useContext(UserContext);
return <p>爷爷的名字:{user.name}</p>;
}
// 中间组件:不需要传递props
function Father() {
return <Grandson />;
}
可以简单的理解成,在最上层使用Provider 申明createContext创建的context;
然后下面的层级使用useContext都可以获取到去使用。
useEffect 副作用
可以简单的理解成,监控某值,当值发生变化,就会触发一些操作;
"副作用"是组件渲染外的操作(如请求数据、定时器);useEffect会在组件渲染后执行。
useEffect(
() => {
// 副作用逻辑
return () => { /* 清理函数(可选) */ }
},
dependencies
);
- 第一个参数:一个包含副作用逻辑的函数(必填)
- 第二个参数:依赖数组(可选),用于控制副作用的执行时机。
- 返回值:清理函数(可选),用于在组件卸载或下次副作用执行前释放资源。