
哈喽,大家好,关注公众号:小码农岛 后台发送 idea,免费送你激活码,快来领取吧,机会难得哦!(仅限学习交流,商用请支持正版)
对于熟悉Vue的来说,React的学习曲线主要来自思维方式的转变。我会尽量用通俗易懂的方式,结合自己的实战经验,用你熟悉的Vue知识作为跳板,系统性地掌握React的核心概念。每个知识点都将配以具体场景说明,确保零基础也能理解。
Vue的组件系统非常直观,采用文件分离的组件结构。我们来看一个典型的Vue组件长什么样:
<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>这种组织方式有几个明显的好处:
React的组件思想完全不同,它认为"组件就是一个返回UI的函数",采用JSX语法将HTML直接嵌入JavaScript。同样的功能,用React实现是这样的:
function MyButton() {
// 事件处理函数直接写在组件内部
const sayHello = () => {
console.log('你好,React!')
}
// 返回JSX描述UI
return (
<button
onClick={sayHello}
style={{ backgroundColor: '#61dafb' }}
>
点击我
</button>
)
}React组件的特点:
注意:JSX虽然看起来像HTML,但本质上是JavaScript的语法糖。编译后其实就是React.createElement()的调用。
Vue的状态管理非常"自动化",通过Proxy实现自动依赖追踪:
<script setup>
const count = ref(0) // 定义一个响应式变量
// 修改值会自动更新UI
const increment = () => {
count.value++ // 注意要用.value访问
}
</script>
<template>
<button @click="increment">{{ count }}</button>
</template>Vue的响应式系统工作原理:
ref或reactive创建响应式数据React的状态管理像手动挡,需要开发者更主动地控制,通过状态更新函数实现显式更新:
function Counter() {
const [count, setCount] = useState(0) // 定义状态
// 必须通过setCount更新状态
const increment = () => {
setCount(count + 1) // 或者 setCount(c => c + 1)
}
return <button onClick={increment}>{count}</button>
}React状态管理要点:
useState定义状态变量和更新函数常见误区:很多Vue转React的开发者会尝试直接修改状态变量,这是不行的。在React中,必须通过setter函数来更新状态。
Vue使用@符号简化事件绑定:
<template>
<button @click="handleClick">点击</button>
<!-- 可以传递参数 -->
<button @click="handleButtonClick('参数')">带参数</button>
<!-- 访问原生事件 -->
<input @input="handleInput($event)" />
</template>React的事件处理更接近原生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>
)
}关键区别:
@click,React使用onClick(注意大小写)Vue使用v-for指令渲染列表:
<template>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
</template>React使用JavaScript的map方法渲染列表:
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>
)
}重要注意事项:
key属性key应该是一个稳定的标识符(最好用id而不是数组索引)key帮助框架高效更新列表,不要忽略它!Vue提供了明确的生命周期钩子函数:
<script setup>
import { onMounted, onUpdated, onUnmounted } from 'vue'
onMounted(() => {
console.log('组件挂载完成')
})
onUpdated(() => {
console.log('组件更新了')
})
onUnmounted(() => {
console.log('组件即将卸载')
})
</script>React使用useEffect统一处理副作用:
import { useEffect } from 'react'
function LifecycleDemo() {
useEffect(() => {
console.log('组件挂载完成')
return () => {
console.log('组件即将卸载')
}
}, []) // 空数组表示只在挂载和卸载时执行
useEffect(() => {
console.log('状态变化导致更新')
}) // 没有依赖数组表示每次渲染都执行
}理解useEffect:
[]相当于componentDidMount生命周期阶段 | Vue (组合式) | React (Hooks) | 示例场景 |
|---|---|---|---|
组件挂载 | onMounted | useEffect(() => {}, []) | DOM操作、数据请求 |
组件更新 | onUpdated | useEffect(() => {}) | 状态变化后操作 |
组件卸载 | onUnmounted | useEffect(() => { return () => {} }, []) | 清除定时器、取消请求 |
状态监听 | watch(source, cb) | useEffect(() => {}, deps) | 特定数据变化时执行操作 |
<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>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.memo和useMemo优化技巧,但别过早优化。
多写多练是关键,React的函数式思维需要适应期。遇到问题别急,保持耐心。工具先用官方的,熟练后再扩展。
记住,框架只是工具,没有绝对的优劣。选择适合你和团队的技术栈才是最重要的。希望这篇文章能帮助你顺利过渡到React开发!
如果还在为面试八股文头疼?关注公众号 小码农岛,后台发送 66 免费领取《面试高频题宝典》,涵盖Java/MySQL/Redis/分布式等热门考点,助你轻松斩获Offer!
OK,今天的分享就到这里。欢迎「点赞+在看」支持!你对此有什么看法?欢迎在评论区分享您的观点。最后非常感谢大家的支持!你们的支持是我写作路上最大的动力。我们下期再见!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。