React框架学习笔记及实践 | 青训营

79 阅读2分钟

学习完JavaScript语法后,我第一个想学习的就是React框架,这里是我学习React框架的一些学习笔记:

JSX语法:JSX是React的标志性语法,它类似HTML但可以执行JavaScript代码。JSX会被编译为 React.createElement方法调用,用于描述界面如何渲染。

组件:React通过组件化的思想来构建界面。组件接收props参数,根据state内部状态渲染不同界面。组件分函数组件和类组件。

State与Props:State是组件内部私有状态,可以通过设置this.state来定义,并通过this.setState修改生成新state。Props是外部传入组件的配置参数,组件内部无法修改。

处理事件:React组件处理事件需要绑定this,通常在构造函数中bind或使用箭头函数。事件绑定语法是onClick等。

组件生命周期:组件生命周期包含挂载、更新、卸载等阶段,可以在对应函数componentDidMount等中编写代码。

React Hooks:Hooks让函数组件也可以使用state等功能。useState是定义state的Hook,useEffect处理副作用。自定义Hook也很有用。

虚拟DOM:React使用虚拟DOM计算最小化的实际DOM操作,提高渲染性能。状态变更后比较虚拟DOM差异重新渲染。

下面是我学习React框架遇到的一些易错易混淆的点:

state 和 props:state是组件内部的状态,可以通过this.setState()修改;props是从外部传入的配置参数,组件内部无法修改。

组件的mount和update:组件mount只在组件初始化渲染时触发一次,update会在组件重新渲染时触发。

shouldComponentUpdate():这个方法控制组件是否重新渲染,需要返回boolean值,不要忘记return语句。

组件生命周期函数:组件生命周期函数中,componentWillMount和componentWillUpdate在新版本中已废弃。

绑定事件this指向:绑定事件需要bind(this)或者使用箭头函数,否则this指向会错误。

Hooks使用规则:Hook的调用要在函数最外层,不能在条件判断里使用,依赖必须固定。

setState异步更新:setStatemutations可能是异步的,不能依赖当前状态计算下一个状态。

函数组件和类组件区别:函数组件简单,无状态;类组件可以有自己的状态和生命周期。

最后贴一下我的实践代码实现一个To-do-list:

import React, { useState } from 'react';

function TodoList() {
  const [todos, setTodos] = useState([
    { text: 'Learn React', completed: false },
    { text: 'Build an app', completed: false }  
  ]);

  const addTodo = text => {
    const newTodos = [...todos, { text }];
    setTodos(newTodos);
  }

  const completeTodo = index => {
    const newTodos = [...todos];
    newTodos[index].completed = true;
    setTodos(newTodos);
  }

  const removeTodo = index => {
    const newTodos = [...todos];
    newTodos.splice(index, 1);
    setTodos(newTodos);
  }

  return (
    <div>
      <div>
        {todos.map((todo, index) => (
          <div key={index}>
            <input 
              type="checkbox" 
              checked={todo.completed} 
              onChange={() => completeTodo(index)} 
            />
            {todo.text}
            <button onClick={() => removeTodo(index)}>x</button>
          </div>
        ))}
      </div>

      <input type="text" onKeyDown={e => {
        if (e.key === 'Enter') {
          addTodo(e.target.value);
          e.target.value = '';
        }
      }} />

      <div>
        Uncompleted todos: {todos.filter(todo => !todo.completed).length}
      </div>
    </div>
  );
}

export default TodoList;