React和Vue的区别
特性 | react | vue |
创建组件 | jsx(js语法扩展,允许js中迁入html结构) 转换为React.createElement('h1', { className: 'greeting' }, 'Hello, world!') 函数组件或类组件 | .vue文件 模板脚本样式 |
模板语法 | 事件属性采用小驼峰 | v-bind v-model绑定数据 插值表达式 |
组件的状态管理 | usestate 类组件this.state | data函数 |
事件绑定 | 小驼峰 | v-on @ |
计算属性和方法 | js | computed methods |
生命周期钩子 | 挂载 componentDidMount更新 shouldComponentUpdate 卸载 componentWillUnmoun | mounted, created, beforeDestroy |
条件渲染 | js 三元运算符 或 && | v-if, v-else 和 v-show |
列表渲染 | map | v-for |
css样式 | 外部 CSS 文件、CSS-in-JS 库(如 styled-components) | scoped |
Props和事件传递 | props | props $emit |
组件封装 | 通过props传递数据和回调 | |
文件结构 | pages hooks components redux | |
语法 | {}包裹表达式、变量、函数或props | |
React钩子
钩子 | 描述 |
useState | 管理组件状态 |
useEffect | 处理副作用(数据请求、dom操作、清理等异步操作) |
useContext | 获取跨组件传递数据 createContext 创建上下文默认值 |
useReducer | 复杂的状态管理 |
useCallback | 避免在组件重新渲染时创建新的回调函数,优化性能,当依赖值变化才更新 |
useMemo | 缓存计算结果,当依赖值变化才更新 |
useRef | 获取dom元素 |
useImperativeHandle | 父组件访问子组件实例暴露内容 forwardRef 允许在函数组件中转发ref |
useLayoutEffect | dom更新前执行,布局测量 |
useDebugValue | 调试自定义hook |
React代码汇总
// File: MyComponent.js
import React, { useState, useEffect, createContext, useContext, useReducer, useCallback, useMemo, useRef, useImperativeHandle, forwardRef,useLayoutEffect, useDebugValue } from 'react';
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
function useCustomHook(value) {
useDebugValue(value ? 'Active' : 'Inactive');
return value;
}
const MyComponent = forwardRef((props, ref) => {
const { onClick, a, b } = props;
const [message, setMessage] = useState('Hello React!');
const style = {
color: 'blue'
};
const ThemeContext = createContext('light');
const theme = useContext(ThemeContext);
const [state, dispatch] = useReducer(reducer, initialState);
const expensiveValue = useMemo(() => a * b, [a, b]);
const inputRef = useRef(null);
const focusInput = () => {
inputRef.current.focus();
};
useImperativeHandle(ref, () => ({
focus: () => inputRef.current.focus()
}));
useLayoutEffect(() => {
console.log(inputRef.current.clientHeight);
}, []);
useEffect(() => {
// 组件挂载或更新时执行
console.log('Component is mounted or updated');
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setMessage(message));
const timer = setInterval(() => {
console.log('Tick');
}, 1000);
// 可选的清理函数
return () => {
console.log('Component will unmount or update');
clearInterval(timer) // 清理定时器
};
}, [message]); // 依赖项数组,只有 message 改变时才会重新执行 useEffect
return (
<div className={props.className}>
<h1>{message}</h1>
<input value={message} onChange={(e) => setMessage(e.target.value)} />
<button onClick={handleClick}>Click Me</button>
isVisible && <div>Visible</div>
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
<h1 style={style}>Hello React!</h1>
<Child message={parentMessage} onUpdate={handleUpdate} />
<div>The current theme is {theme}</div>
<p>{state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={onClick}>Click me</button>
<div>{expensiveValue}</div>;
<input ref={inputRef} />
<button onClick={focusInput}>Focus the input</button>
</div>
);
})
export default MyComponent;
// File: App.js
import React, { useState, useCallback, useRef } from 'react';
import MyComponent from './MyComponent';
function App() {
const [count, setCount] = useState(0);
const memoizedCallback = useCallback(() => {
setCount(count + 1);
}, [count]);
const childRef = useRef();
const handleAnotherAction = () => {
alert('Another action triggered!');
};
return (
<React.Fragment>
<ThemeContext.Provider value="dark">
<MyComponent onClick={memoizedCallback} ref={childRef} className="primary-btn" onAction={handleAnotherAction} />
</ThemeContext.Provider>
<button onClick={() => childRef.current.focus()}>Focus Input</button>
</React.Fragment>
);
}
export default App;
React和Vue代码对比
