首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >在公司花了半小时摸鱼时间,我学会了React

在公司花了半小时摸鱼时间,我学会了React

原创
作者头像
Xwaiy
发布2025-06-21 14:09:17
发布2025-06-21 14:09:17
3060
举报

哈喽,大家好,关注公众号:小码农岛 后台发送 idea,免费送你激活码,快来领取吧,机会难得哦!(仅限学习交流,商用请支持正版)

对于熟悉Vue的来说,React的学习曲线主要来自思维方式的转变。我会尽量用通俗易懂的方式,结合自己的实战经验,用你熟悉的Vue知识作为跳板,系统性地掌握React的核心概念。每个知识点都将配以具体场景说明,确保零基础也能理解。

先聊聊组件:两种不同的设计思路

Vue的模块化组件

Vue的组件系统非常直观,采用文件分离的组件结构。我们来看一个典型的Vue组件长什么样:

代码语言:javascript
复制
 <template>
   <!-- 这里是HTML模板 -->
   <button @click="sayHello">点击我</button>
 </template>
 
 <script setup>
 // 这里是JavaScript逻辑
 const sayHello = () => {
   console.log('你好,Vue!')
 }
 </script>
 
 <style scoped>
 /* 这里是CSS样式,scoped表示只在这个组件生效 */
 button {
   background-color: #42b983;
 }
 </style>

这种组织方式有几个明显的好处:

  1. 结构清晰:HTML、JS、CSS各司其职,一目了然
  2. 学习成本低:特别适合刚入门的前端开发者
  3. 样式隔离:scoped样式不会影响其他组件

React的组件更像是JavaScript函数

React的组件思想完全不同,它认为"组件就是一个返回UI的函数",采用JSX语法将HTML直接嵌入JavaScript。同样的功能,用React实现是这样的:

代码语言:javascript
复制
 function MyButton() {
   // 事件处理函数直接写在组件内部
   const sayHello = () => {
     console.log('你好,React!')
   }
 
   // 返回JSX描述UI
   return (
     <button 
       onClick={sayHello}
       style={{ backgroundColor: '#61dafb' }}
     >
       点击我
     </button>
   )
 }

React组件的特点:

  1. 全JavaScript实现:没有单独的模板,UI也用JS写(JSX)
  2. 更灵活:可以充分利用JavaScript的全部能力
  3. 需要适应:对于习惯HTML/CSS分离的开发者需要转变思维

注意:JSX虽然看起来像HTML,但本质上是JavaScript的语法糖。编译后其实就是React.createElement()的调用。

状态管理

Vue的响应式

Vue的状态管理非常"自动化",通过Proxy实现自动依赖追踪

代码语言:javascript
复制
 <script setup>
 const count = ref(0) // 定义一个响应式变量
 
 // 修改值会自动更新UI
 const increment = () => {
   count.value++ // 注意要用.value访问
 }
 </script>
 
 <template>
   <button @click="increment">{{ count }}</button>
 </template>

Vue的响应式系统工作原理:

  1. 通过refreactive创建响应式数据
  2. 当数据变化时,Vue自动检测到变化
  3. 自动更新所有用到这个数据的地方

React的状态管理

React的状态管理像手动挡,需要开发者更主动地控制,通过状态更新函数实现显式更新

代码语言:javascript
复制
 function Counter() {
   const [count, setCount] = useState(0) // 定义状态
 
   // 必须通过setCount更新状态
   const increment = () => {
     setCount(count + 1) // 或者 setCount(c => c + 1)
   }
 
   return <button onClick={increment}>{count}</button>
 }

React状态管理要点:

  1. 使用useState定义状态变量和更新函数
  2. 必须通过更新函数修改状态
  3. 状态更新是异步的,可能会被批量处理
  4. 遵循不可变原则,不要直接修改状态

常见误区:很多Vue转React的开发者会尝试直接修改状态变量,这是不行的。在React中,必须通过setter函数来更新状态。

处理用户交互:事件绑定的差异

Vue中的事件处理

Vue使用@符号简化事件绑定:

代码语言:javascript
复制
 <template>
   <button @click="handleClick">点击</button>
   
   <!-- 可以传递参数 -->
   <button @click="handleButtonClick('参数')">带参数</button>
   
   <!-- 访问原生事件 -->
   <input @input="handleInput($event)" />
 </template>

React中的事件处理

React的事件处理更接近原生JavaScript:

代码语言:javascript
复制
 function EventDemo() {
   const handleClick = () => {
     console.log('按钮被点击了')
   }
 
   return (
     <div>
       {/* 直接传递函数引用 */}
       <button onClick={handleClick}>点击</button>
       
       {/* 传递参数需要使用箭头函数 */}
       <button onClick={() => handleButtonClick('参数')}>带参数</button>
       
       {/* 事件对象会自动传递 */}
       <input onChange={(e) => console.log(e.target.value)} />
     </div>
   )
 }

关键区别

  1. Vue使用@click,React使用onClick(注意大小写)
  2. React事件处理函数需要手动绑定参数
  3. React的事件对象是合成事件(SyntheticEvent),和原生事件稍有不同

列表渲染

Vue的v-for指令

Vue使用v-for指令渲染列表:

代码语言:javascript
复制
 <template>
   <ul>
     <li v-for="item in items" :key="item.id">
       {{ item.name }}
     </li>
   </ul>
 </template>

React使用map方法

React使用JavaScript的map方法渲染列表:

代码语言:javascript
复制
 function ItemList() {
   const items = [
     { id: 1, name: '项目1' },
     { id: 2, name: '项目2' }
   ]
 
   return (
     <ul>
       {items.map(item => (
         <li key={item.id}>{item.name}</li>
       ))}
     </ul>
   )
 }

重要注意事项

  1. 无论是Vue还是React,都必须为列表项提供唯一的key属性
  2. key应该是一个稳定的标识符(最好用id而不是数组索引)
  3. key帮助框架高效更新列表,不要忽略它!

生命周期

Vue的生命周期钩子

Vue提供了明确的生命周期钩子函数:

代码语言:javascript
复制
<script setup>
import { onMounted, onUpdated, onUnmounted } from 'vue'

onMounted(() => {
  console.log('组件挂载完成')
})

onUpdated(() => {
  console.log('组件更新了')
})

onUnmounted(() => {
  console.log('组件即将卸载')
})
</script>

React的useEffect Hook

React使用useEffect统一处理副作用:

代码语言:javascript
复制
import { useEffect } from 'react'

function LifecycleDemo() {
  useEffect(() => {
    console.log('组件挂载完成')
    
    return () => {
      console.log('组件即将卸载')
    }
  }, []) // 空数组表示只在挂载和卸载时执行

  useEffect(() => {
    console.log('状态变化导致更新')
  }) // 没有依赖数组表示每次渲染都执行
}

理解useEffect

  1. 第一个参数是副作用函数
  2. 可选的返回函数是清理函数
  3. 第二个参数是依赖数组,控制何时重新执行
  4. 空依赖数组[]相当于componentDidMount

生命周期阶段

Vue (组合式)

React (Hooks)

示例场景

组件挂载

onMounted

useEffect(() => {}, [])

DOM操作、数据请求

组件更新

onUpdated

useEffect(() => {})

状态变化后操作

组件卸载

onUnmounted

useEffect(() => { return () => {} }, [])

清除定时器、取消请求

状态监听

watch(source, cb)

useEffect(() => {}, deps)

特定数据变化时执行操作

实战

Vue版本实现

代码语言:javascript
复制
<template>
  <div>
    <input 
      v-model="newTodo" 
      @keyup.enter="addTodo"
      placeholder="输入待办事项"
    />
    <ul>
      <li v-for="todo in todos" :key="todo.id">
        <input 
          type="checkbox"
          v-model="todo.completed"
        />
        <span :class="{ completed: todo.completed }">
          {{ todo.text }}
        </span>
        <button @click="removeTodo(todo.id)">删除</button>
      </li>
    </ul>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const newTodo = ref('')
const todos = ref([])

const addTodo = () => {
  if (newTodo.value.trim()) {
    todos.value.push({
      id: Date.now(),
      text: newTodo.value,
      completed: false
    })
    newTodo.value = ''
  }
}

const removeTodo = (id) => {
  todos.value = todos.value.filter(todo => todo.id !== id)
}
</script>

<style>
.completed {
  text-decoration: line-through;
  color: #999;
}
</style>

React版本实现

代码语言:javascript
复制
import { useState } from 'react'

function TodoApp() {
  const [newTodo, setNewTodo] = useState('')
  const [todos, setTodos] = useState([])

  const addTodo = () => {
    if (newTodo.trim()) {
      setTodos([
        ...todos,
        {
          id: Date.now(),
          text: newTodo,
          completed: false
        }
      ])
      setNewTodo('')
    }
  }

  const toggleTodo = (id) => {
    setTodos(todos.map(todo =>
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    ))
  }

  const removeTodo = (id) => {
    setTodos(todos.filter(todo => todo.id !== id))
  }

  return (
    <div>
      <input
        value={newTodo}
        onChange={(e) => setNewTodo(e.target.value)}
        onKeyUp={(e) => e.key === 'Enter' && addTodo()}
        placeholder="输入待办事项"
      />
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>
            <input
              type="checkbox"
              checked={todo.completed}
              onChange={() => toggleTodo(todo.id)}
            />
            <span style={{ 
              textDecoration: todo.completed ? 'line-through' : 'none',
              color: todo.completed ? '#999' : 'inherit'
            }}>
              {todo.text}
            </span>
            <button onClick={() => removeTodo(todo.id)}>删除</button>
          </li>
        ))}
      </ul>
    </div>
  )
}

从Vue到React要循序渐进,先从小功能入手。用Create React App快速启动,搭配ESLint+TS保证质量。重点掌握React.memouseMemo优化技巧,但别过早优化。

多写多练是关键,React的函数式思维需要适应期。遇到问题别急,保持耐心。工具先用官方的,熟练后再扩展。

记住,框架只是工具,没有绝对的优劣。选择适合你和团队的技术栈才是最重要的。希望这篇文章能帮助你顺利过渡到React开发!

最后想说

如果还在为面试八股文头疼?关注公众号 小码农岛,后台发送 66 免费领取《面试高频题宝典》,涵盖Java/MySQL/Redis/分布式等热门考点,助你轻松斩获Offer!

OK,今天的分享就到这里。欢迎「点赞+在看」支持!你对此有什么看法?欢迎在评论区分享您的观点。最后非常感谢大家的支持!你们的支持是我写作路上最大的动力。我们下期再见!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 先聊聊组件:两种不同的设计思路
    • Vue的模块化组件
    • React的组件更像是JavaScript函数
  • 状态管理
    • Vue的响应式
    • React的状态管理
  • 处理用户交互:事件绑定的差异
    • Vue中的事件处理
    • React中的事件处理
  • 列表渲染
    • Vue的v-for指令
    • React使用map方法
  • 生命周期
    • Vue的生命周期钩子
    • React的useEffect Hook
  • 实战
    • Vue版本实现
    • React版本实现
  • 最后想说
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档