用了段时间vue做了几个项目,感觉挺好用啊,但是不少人认为用vue就能力/水平最差(真就越容易上手就越被鄙视呗,就和php的处境一样),这。。。 个人觉得用框架不管用哪个都是基础,不都是用框架,为什么还要搞个鄙视链出来?用哪个框架不存在会不会,只在于想不想用,废话不多说,开始:
提示:本文站在vue用户的角度通过对比的方式对常用场景进行介绍和总结,以便快速上手react,深度有限,欢迎讨论交流。
1、组件
Vue: 一个(包含data、生命周期钩子、methods、template等特殊属性的)JavaScript对象;
React: 一个函数或一个(继承React.Component类并且包含一个render方法的)类。
render函数的返回值为被括号包裹的jsx。
jsx:具有 JavaScript 的全部功能的xml模板语言,和vue的template里的东西很像。
2、传值
— 父传子
Vue:
- 父组件通过组件属性的形式把方法或值传递到子组件,子组件在props属性中定义值的类型(Sting|Number|Function…)然后接收,通过`this.
属性名`
方式使用。 - 父组件通过this.$refs[子组件ref值]访问子组件方法,从而通过函数传参的方式进行传值。
React:
- 父组件通过组件属性的形式把方法或值传递到子组件,子组件中通过
this.props.属性名
的方式获传递的值。
官网案例:
// 已经删除无关代码
// 父组件
class Game extends React.Component
{
constructor(props) {
super(props);
this.state = {
boardSize:9, // 棋盘大小
history: [ // 落子历史
{ squares: Array(9).fill(null) }
],
xIsNext: true, // 是否该黑棋走棋
};
}
handleXIsNext(val) {
this.setState({ xIsNext: !this.state.xIsNext });
console.log(val, this.state.xIsNext);
}
render(){
return (
<div className='game'>
<div className='game-board'>
<Board data={this.state} changeXIsNext={(val) => { this.handleXIsNext(val)}}/>
</div>
// ...
</div>
)
}
}
// 子组件
class Board extends React.Component
{
constructor(props) {
super(props);
// ...
}
// 当方格被点击时更新方格的状态,并通知到Game
clickHandler() {
// ...
this.props.changeXIsNext(null);
}
render() {
return <Square onClick={() => this.clickHandler()} />
}
}
发射点发生
— 子传父
Vue:
- 通过this.$emit(eventName, data)方法发送事件,父组件通过监听事件(即:@eventName)绑定回调函数接收。
React:
- 通过调用父组件传递过来的函数实现传值。
案例:
// 父组件
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />;
}
}
// 子组件
class Square extends React.Component {
render() {
return (
<button className="square">
{this.props.value}
</button>
);
}
}
3、全局状态管理
Vue:
- 通过Vue.prototype将值挂载到上。
- 使用Vuex(第三方)。
React:
- props通过一个全局对象来中转,一个组件向其中存放数据,另一个组件取出来的方式来通信(繁琐,不推荐)。
- redux(第三方,官网文档:搭配 React · Redux https://www.redux.org.cn/docs/basics/UsageWithReact.html)
- context React.createContext 的 api 会返回 Provider 和 Consumer,分别用于提供 state 和取 state,而且也是通过 props 来透明的传入目标组件的。
- state class 组件的 state 做不到,function 组件的 state 可以抽离到自定义 hooks 里,然后不同的 function 组件里引入来用。
context 没有执行异步逻辑的中间件,所以 context 这种方案适合没有异步逻辑的那种全局数据通信,而 redux 适合组织复杂的异步逻辑。
案例:
–context
案例:
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
I am styled by theme context!
</button>
);
}
–state
案例:
import React, { useState } from 'react';
const useGlobalState = (initialValue) => {
const [globalState, setGlobalState] = useState(initialValue);
return [globalState, setGlobalState];
}
function ComponentA() {
const [globalState, setGlobalState] = useGlobalState({name: 'aaa'});
setGlobalState({name: bbb});
return <div>{globalState}</div>
}
function ComponentA() {
const [globalState, setGlobalState] = useGlobalState({name: 'aaa'});
return <div>{globalState}</div>
}
4、生命周期函数
Vue:
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDistory
- distoryed
React:
- componentDidmount
- componentDidUpdate
- componentWillunmount
- componentDidunmount
- …
React提倡使用hook,在新版本中大多数生命周期函数都已经被废弃。
5、Hook
Hook 将组件中相互关联的部分拆分成更小的函数(比如设置订阅或请求数据),使你在非 class 的情况下可以使用更多的 React 特性。
文档: Hook API 索引 – React (reactjs.org) https://zh-hans.reactjs.org/docs/hooks-reference.html
- useState 它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
- useEffect 默认情况下,effect 将在每轮渲染结束后执行,但你可以选择让它 在只有某些值改变的时候 才执行。
官网案例:
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
—未完待续
最后更新于:2022-06-01