react学习笔记

class属性要写成className

<div className="box">内容</div>

事件名要驼峰式命名

比如HTML中的onclick,在JSX中要写成onClickonchange写成onChange

组件的函数名必须首字母大写,普通标签小写

function Welcome() {

    return <h1>欢迎学习React组件化!</h1>;

}

父组件给子组件传值props

function App() {
  const userInfo = {
    title: "个人信息",
    content: "姓名:小明,年龄:20"
  };

  return (
    <div>
              {/* 传递第1组数据:直接写死值 */}
              <Child title="课程介绍" 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]

);

  • 第一个参数:一个包含副作用逻辑的函数(必填)
  • 第二个参数:依赖数组(可选),用于控制副作用的执行时机。
  • 返回值:清理函数(可选),用于在组件卸载或下次副作用执行前释放资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值