React笔记(一)

2024 年 5 月 3 日 星期五(已编辑)
/
14
摘要
这段内容主要介绍了如何创建React程序,React的渲染流程,JSX的本质以及基础事件绑定。同时还介绍了React组件的基本类型和数据传递,以及如何使用useState来管理状态。最后也提到了React样式的基本用法。
这篇文章上次修改于 2024 年 5 月 7 日 星期二,可能部分内容已经不适用,如有疑问可询问作者。

阅读此文章之前,你可能需要首先阅读以下的文章才能更好的理解上下文。

1.创建React程序

npx create-react-app 项目名

React渲染流程

App.js -> index.js -> index.html(root)

JSX本质

JS的扩展语法(语法糖),通过解析工具解析后在浏览器中运行

JSX的本质是将类似XML的标记转换为JavaScript对象。当编写JSX代码时,开发者 可以使用类似HTML的标签和属性,但在底层,这些标记会被转换为React.createElement()函数的调用,返回一个描述UI元素的JavaScript对象

  • 转换前

    const element = <h1 className="greeting">Hello, World!</h1>;

    转换后

    const element = React.createElement('h1', { className: 'greeting' }, 'Hello, World!');

JSX通过{ }来识别JS表达式

const count = 100;

function getCount() {
  return count;
}

function countDelete(){
  for (var i = 0; i < count; i++){
    console.log(i);
  }
}

function App() {
  return (
    <div className="App">
      this is App
      {/* 变量调用 */}
      <div>{count}</div>
      {/* 函数调用 */}
      <div>{getCount()}</div>
      <div>{countDelete()}</div>
      {/* 方法调用 */}
      {new Date().getDate()}
      {/* 识别对象 */}
      <div style={{color:'red'}}>hello world</div>  
    </div>
  );
}

export default App;

渲染

列表渲染(通过key来唯一标识加速渲染)

const list =  [
  { id: 1001,name: 'Vue' },
  { id: 1002,name: 'React' },
  { id: 1003,name: 'Angular' }
]

function App() {
  return (
    <div className="App"> 
    <ul>
      {list.map(item=><li key={item.id}>{item.id}--{item.name}</li>)}
    </ul>
    </div>
  );
}

export default App;

条件渲染(React通过逻辑运算符和三元表达式来实现基础条件渲染)

const loading = 0;
const isLogin = true;

function App() {
  return (
    <div className="App">
    {isLogin && <p>you are login in</p>}
    {loading?<span>loading...</span>:<span>this is a span</span>}
    </div>
  );
}

复杂条件渲染

const target = 3
function getArticle() {
  if(target === 0) {
    return <div>无图模式</div>
  }else if(target === 1) {
    return <div>单图模式</div>
  }else if(target === 3) {
    return <div>多图模式</div>
  }
}

function App() {
  return (
    <div className="App">
      {getArticle()}
    </div>
  );
}

React基础事件绑定

function App() {
  function clickHandler() {
    return alert("hello world")
  }

  return (
    <div className="App">
      <button onClick={clickHandler}>button</button>
    </div>
  );
}

//事件参数e
function App() {
  const clickHandler = (e) => {
    console.log(e)
  }

  return (
    <div className="App">
      <button onClick={clickHandler}>button</button>
    </div>
  );
}

//传自定义值
function App() {
  const clickHandler = (name) => {
    console.log(name)
  }

  return (
    <div className="App">
      <button onClick={()=>clickHandler('jack')}>button</button>
    </div>
  );
}

//即传事件参数又传自定义值
function App() {
  const clickHandler = (name, e) => {
    console.log(e,name)
  }

  return (
    <div className="App">
      <button onClick={(e) => clickHandler('jack', e)}>button</button>
    </div>
  );
}

2.React常用的事件绑定

onClick事件:

class MyComponent extends React.Component {
  handleClick = () => {
    // 处理点击事件的逻辑
  };

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    );
  }
}

onChange事件(通常用于表单元素):

class MyForm extends React.Component {
  handleChange = (event) => {
    // 处理输入值变化的逻辑
  };

  render() {
    return (
      <input type="text" onChange={this.handleChange} />
    );
  }
}

onSubmit事件(通常用于表单提交):

class MyForm extends React.Component {
  handleSubmit = (event) => {
    // 处理表单提交的逻辑
    event.preventDefault(); // 阻止默认的表单提交行为
  };

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        {/* 表单内容 */}
        <button type="submit">Submit</button>
      </form>
    );
  }
}

其他常见事件(例如鼠标悬停):

class MyComponent extends React.Component {
  handleMouseOver = () => {
    // 处理鼠标悬停的逻辑
  };

  render() {
    return (
      <div onMouseOver={this.handleMouseOver}>
        Hover over me
      </div>
    );
  }
}

3.React组件

在React中,组件是构建用户界面的基本单元,可以是函数组件或类组件。组件可以包含其他组件,形成组件树,这样整个应用程序的界面就被分解成了独立且可复用的部分。以下是React中常见的组件类型和一些示例:

  1. 函数组件: 使用函数声明的组件,接收一个props对象作为参数,返回一个React元素。函数组件是无状态的,通常用于简单的UI部分。

    function MyFunctionalComponent(props) {
      return <div>Hello, {props.name}!</div>;
    }
  2. 类组件: 使用ES6类语法声明的组件,继承自React.Component。类组件有自己的状态(state)和生命周期方法,适用于需要内部状态或生命周期处理的情况。

    class MyClassComponent extends React.Component {
      constructor(props) {
        super(props);
        this.state = { count: 0 };
      }
    
      render() {
        return <div>Count: {this.state.count}</div>;
      }
    }
  3. 使用Hooks的函数组件: 使用Hooks(如useStateuseEffect)可以在函数组件中使用状态和生命周期等功能。

    import React, { useState, useEffect } from 'react';
    
    function MyFunctionalComponentWithHooks() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        // 处理副作用,类似于componentDidMount和componentDidUpdate
        document.title = `Count: ${count}`;
      }, [count]);
    
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={() => setCount(count + 1)}>Increment</button>
        </div>
      );
    }
  4. 组件之间的数据传递: 父组件可以通过props向子组件传递数据,子组件可以通过回调函数将数据传递回父组件。

    //ParentComponent.jsx
    import React from 'react';
    import ChildComponent from './ChildComponent';
    
    function ParentComponent() {
      const handleChildData = (data) => {
        console.log(`Data from child: ${data}`);
      };
    
      return <ChildComponent onData={handleChildData} />;
    }
    // ChildComponent.jsx
    import React from 'react';
    
    function ChildComponent({ onData }) {
      const sendDataToParent = () => {
        const data = 'Hello from child!';
        onData(data);
      };
    
      return (
        <div>
          <button onClick={sendDataToParent}>Send Data</button>
        </div>
      );
    }

自测

function handerTest() {
  alert('hello world')
}

function Button() { 
  return <button onClick={handerTest}>click me!</button>
}

function App() {
  return (
    <div className="App">
      <Button />
    </div>
  );
}

浏览器waring

[Violation] 'click' handler took 1189ms
[Violation] 'click' handler took 1189ms
react-dom.development.js:4161 [Violation] 'click' handler took 864ms
[Violation] 'click' handler took 867ms

解释

    这些警告信息是浏览器开发者工具提供的性能提示,它们指示在处理点击事件时花费的时间较长。这可能是由于事件处理函数中执行的操作过于耗时,导致页面性能下降。

要解决这个问题,可以考虑以下几点:
优化事件处理函数: 确保事件处理函数内的代码是高效的。避免在事件处理函数中执行复杂或耗时的操作,尤其是在用户与页面交互时。如果有必要执行长时间运行的任务,可以考虑使用异步操作或将其拆分成多个步骤。

懒加载和分割代码: 如果应用程序包含大量代码,可以考虑使用懒加载(Lazy Loading)和代码分割(Code Splitting)来延迟加载部分代码。这有助于减少初始加载时的工作量,提高页面响应速度。

性能分析工具: 使用浏览器提供的性能分析工具,例如Chrome的Performance面板,来检查哪些部分的代码执行时间较长。这有助于定位性能瓶颈并进行优化。

React性能优化: 使用React提供的性能优化技术,例如React.memo、useMemo和useCallback,以避免不必要的重新渲染和函数重复执行。

修改后

import React, { useCallback } from 'react';

function Button() {
  const handleClick = useCallback(() => {
    // 你的点击事件处理逻辑
    alert('hello world');
  }, []);

  return <button onClick={handleClick}>点击我!</button>;
}

4.useState

useState是一个Hook 函数,允许我们向组件传递一个状态变量,通过状态变量的值来影响组件渲染数据驱动视图

const [count,setCount] = useState(0)
//useState是一个函数,返回值是一个数组
//数组的第一个参数是状态变量,第二个参数是set函数用来修改状态变量
//useState的参数将作为count的初始值
import { useState } from 'react';

//简易计数器
function App() {
  const [count, setCount] = useState(0)

  const handleClick = ()=> {
    setCount(count+1)
  }
  return (
    <div className="App">
      <button onClick={handleClick}>{count}</button>
    </div>
  );
}

复杂类型对象

import { useState } from 'react';

function App() {
  const [Form, setForm] = useState({name: 'linmo'})

  const handleClick = ()=> {
    setForm({
      ...Form,
      name: 'limin'
    })
  }
  return (
    <div className="App">
      <button onClick={handleClick}>{Form.name}</button>
    </div>
  );
}

状态不可变

在React中,状态被认为只是可读的,我们应该始终替换它而不是修改它,即不通过setCount函数,直接修改状态变量不会引发组件视图的更新

5.React样式基础

//导入样式
import './index.css'

function App() {
  return (
    <div className="App">
      <p className='test'>hello world</p>
    </div>
  );
}
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...