日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢(xún)客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

為什么要從 Vue 轉(zhuǎn)到 React,這篇文章為什么我們放棄了 Vue?不過(guò)對(duì)于大多數(shù)人來(lái)說(shuō),用 Vue 還是 React 不是自己說(shuō)了算,多學(xué)一門(mén)技術(shù)不是壞處,而且 React 被大廠大量使用,要進(jìn)入大廠也是必備的技能,筆者原先使用 Vue,由于 React 相關(guān)概念更加簡(jiǎn)單,只要會(huì) js 就行,轉(zhuǎn)到 React 只花了幾天時(shí)間(已經(jīng)回不去了~)。本文寫(xiě)給想從 Vue 轉(zhuǎn)到 React 的同學(xué),假設(shè)讀者有一定的 Vue 基礎(chǔ)。

JSX

先介紹 React 唯一的一個(gè)語(yǔ)法糖:JSX。

<div class='box' id='content'>
  <div class='title'>Hello</div>
  <button>Click</button>
</div>

上面的 DOM 結(jié)構(gòu)可以看出,要每個(gè)標(biāo)簽只有 3 個(gè)信息:標(biāo)簽名、屬性、子元素,所以上面等同于下面的 JSON 結(jié)構(gòu):

{
  tag: 'div',
  attrs: { className: 'box', id: 'content'},
  children: [
    {
      tag: 'div',
      arrts: { className: 'title' },
      children: ['Hello']
    },
    {
      tag: 'button',
      attrs: null,
      children: ['Click']
    }
  ]
}

當(dāng)你寫(xiě)下這個(gè) React 組件是:

import React from 'react';

function MyComponent(props) {
    return <div>{props.hello}</div>
}

最終會(huì)被自動(dòng)工具翻譯成:

import React from 'react';

function MyComponent(props) {
    return React.createElement('div', null, props.hello);
}

理解 JSX 語(yǔ)法并不困難,簡(jiǎn)單記住一句話(huà),遇到 {} 符號(hào)內(nèi)部解析為 JS 代碼,遇到成對(duì)的 <> 符號(hào)內(nèi)部解析為 html 代碼。React 就是通過(guò)這個(gè)小小語(yǔ)法糖,實(shí)現(xiàn)在 JS 里面寫(xiě) HTML,可能有小伙伴會(huì)說(shuō) HTML 與 JS 分離不是更好嗎?責(zé)職分明,混合只會(huì)更亂。但當(dāng)你體驗(yàn)到代碼自動(dòng)提示,自動(dòng)檢查,以及調(diào)試時(shí)精確定位到一行代碼的好處時(shí),就清楚 React 和 Vue 的差距了。

語(yǔ)法糖轉(zhuǎn)換

習(xí)慣 Vue 的同學(xué)都知道很多語(yǔ)法糖,比如 v-if、v-for、v-bind、v-on 等,相比 Vue,React 只有一個(gè)語(yǔ)法糖,那就是 jsx/tsx。v-if 這些功能在 React 上都是通過(guò)原生 JAVAscript 實(shí)現(xiàn)的,慢慢你會(huì)發(fā)現(xiàn),其實(shí)你學(xué)的不是 React,而是 Javascipt,React 賦予你通過(guò) js 完整控制組件的能力,這部分明顯比 Vue 的語(yǔ)法糖更加靈活,糖太多容易引來(lái)蟲(chóng)子(Bug)。

 

v-if 條件渲染

vue 中寫(xiě)法是這樣:

<template>
  <div>
    <h1 v-if="awesome1">Vue is awesome!</h1>
    <h1 v-else>else</h1>
    <h1 v-if="awesome2">Oh no</h1>
  </div>
</template>

<script>
module.exports = {
  data: function() {
    return {
      awesome1: true,
      awesome2: false,
    }
  }
}
</script>

在 React 函數(shù)組件中只需這樣:

import React, { useState } from 'react';

function Index() {
  const [awesome1, setAwesome1] = useState(true);
  const [awesome2, setAwesome2] = useState(false);

  return (
    <div>
      {awesome1 ? <h1>React is awesome!</h1> : <h1>Oh no</h1>}
      {awesome2 && <h1>React is awesome!</h1>}
    </div>
  );
}

export default Index;

只需使用 js 三目運(yùn)算符語(yǔ)法即可完成條件渲染的功能。或者使用 && 邏輯,記住下面一句話(huà)就能過(guò)理解了:

遇到 {} 符號(hào)內(nèi)部解析為 JS 代碼,遇到成對(duì)的 <> 符號(hào)內(nèi)部解析為 HTML 代碼

v-for 列表渲染

Vue 中寫(xiě)法:

<template>
  <ul id="array-rendering">
    <li v-for="item in items">
      {{ item.message }}
    </li>
  </ul>
</template>

<script>
module.exports = {
  data() {
    return {
      items: [{ message: 'Foo' }, { message: 'Bar' }]
    }
  }
}
</script>

React 寫(xiě)法:

import React, { useState } from 'react';

function Index() {
  const [items, setItems] = useState([{ message: 'Foo' }, { message: 'Bar' }]);

  return (
    <ul id="array-rendering">
      {items.map((item, id) => <li key={id}>{item.message}</li>)}
    </ul>
  );
}

export default Index;

React 通過(guò) js 的數(shù)組語(yǔ)法 map,將數(shù)據(jù)對(duì)象映射為 DOM 對(duì)象。只需學(xué)會(huì) js,無(wú)需記住各種指令,如果要做列表過(guò)濾,直接使用 items.filter(...).map(...) 鏈?zhǔn)秸{(diào)用即可,語(yǔ)法上更加靈活,如果為了提高渲染性能,使用 useMemo 進(jìn)行優(yōu)化即可,類(lèi)似 Vue 的 computed。

v-model

Vue 中 v-model 是一個(gè)數(shù)據(jù)綁定語(yǔ)法糖,本質(zhì)上還是單向數(shù)據(jù)流,下面的子組件通過(guò) update:title 同步 title 參數(shù)。

App.component('my-component', {
  props: {
    title: String
  },
  emits: ['update:title'],
  template: `
    <input
      type="text"
      :value="title"
      @input="$emit('update:title', $event.target.value)">
  `
})

React 寫(xiě)法較為簡(jiǎn)單,不需要像 Vue 一樣填鴨代碼,記住各種規(guī)則,所有數(shù)據(jù)和事件通過(guò) props 傳遞就行了:

import React from 'react';

interface Props {
  title: string;
  onUpdateTitle: (title: string) => void;
}

function MyComponent(props: Props) {
  return <input
    type='text'
    value={props.title}
    onInput={e => props.onUpdateTitle(e.target.value)}
  />
}

更加容易整合 typescript 實(shí)現(xiàn)類(lèi)型推斷,需要的邏輯都由 JS 完成,無(wú)需記住各種指令、使用方法,參數(shù)命名規(guī)則。

事件處理

Vue 中寫(xiě)法

<template>
  <div id="inline-handler">
    <button @click="say('hi')">Say hi</button>
    <button @click="say('what')">Say what</button>
  </div>
</template>

<script>
module.exports = {
  methods: {
    say(message) {
      alert(message)
    }
  }
}
</script>

React 寫(xiě)法:

import React, { useState } from 'react';

function Index() {
  const onClick = (message) => () => alert(message);

  return (
    <div id="inline-handler">
      <button onClick={onClick('hi')}>Say hi</button>
      <button onClick={onClick('what')}>Say what</button>
    </div>
  );
}

export default Index;

這里用了函數(shù)柯里化,一般事件處理這樣就行了:

import React from 'react';

function Index() {
  const onClick = () => alert('hi');

  return (
    <div id="inline-handler">
      <button onClick={onClick}>Say hi</button>
    </div>
  );
}

export default Index;

如果需要優(yōu)化緩存事件處理函數(shù),使用 useCallback 即可??梢钥吹?Vue 中的事件觸發(fā) this.$emit('click') 或者父組件中的代碼 v-on="say('hi')" 都使用了字符串的寫(xiě)法,這樣非常不利于類(lèi)型推斷,不利于代碼重構(gòu)。React 的函數(shù)寫(xiě)法或者 class 寫(xiě)法都直接使用 js 語(yǔ)法,沒(méi)有額外的東西,相比 Vue 更容易通過(guò) IDE 進(jìn)行重構(gòu)優(yōu)化。React 中無(wú)論方法還是變量,都是采用駝峰命名法,也可以自由定制,Vue 中必須混合小寫(xiě)中隔線、駝峰、字符串組合,不利于統(tǒng)一代碼規(guī)范。

插槽

Vue 中寫(xiě)法:

<template>
  <button class="btn-primary">
    <slot></slot>
  </button>
</template>

<script>
module.exports = {
  methods: {}
}
</script>

React 寫(xiě)法:

import React from 'react';

function Index() {
  return (
    <button classNames="btn-primary">
      {props.children}
    </button>
  );
}

export default Index;

React 的插槽寫(xiě)法沒(méi)有 Vue 那么復(fù)雜,也沒(méi)有“備用內(nèi)容”、“具名插槽”、“渲染作用域”、“作用域插槽”、“動(dòng)態(tài)插槽名”,這些概念和特殊情況的處理,一切通過(guò) JS 邏輯搞定就行了,怎么方便怎么來(lái),比如備用內(nèi)容的實(shí)現(xiàn):

import React from 'react';

function Index() {
  // 默認(rèn)情況下使用 Summit 作為按鈕文字
  return (
    <button classNames="btn-primary">
      {props.children === null ? 'Summit' : props.children}
    </button>
  );
}

export default Index;

樣式 & 屬性

這部分 Vue 的寫(xiě)法實(shí)在是太麻煩了。。。每次我都要查查文檔具體怎么用,對(duì)象語(yǔ)法、數(shù)組語(yǔ)法、內(nèi)聯(lián)樣式,要記住的有點(diǎn)多,Vue 動(dòng)態(tài)修改樣式的寫(xiě)法:

<template>
  <div
    class="static"
    :class="{ active: isActive, 'text-danger': hasError }"
  ></div>
</template>

<script>
module.exports = {
  data() {
    return {
      isActive: true,
      hasError: false
    }
  }
}
</script>

React 寫(xiě)法:

import React, { useState } from 'react';

function Index() {
  const [isActive, setIsActive] = useState(true);
  const [hasError, setHasError] = useState(false);

  return (
    <div
      classNames={`static ${isActive ? 'active':'} ${hasError? 'text-danger':''}`}
    ></div>
  );
}

export default Index;

React 里面直接采用 JS 的模板字符串語(yǔ)法,如果樣式太多,可以使用 classnames 這個(gè) npm 包,優(yōu)雅傳遞各種狀態(tài),使用非常簡(jiǎn)單:

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'

狀態(tài)管理

Vue 的狀態(tài)管理官方推薦使用 Vuex 也可采用 Redux。

Vue 轉(zhuǎn) React 指南,看這篇文章就夠了

 

引用官方文檔一段話(huà):

如果你是來(lái)自 React 的開(kāi)發(fā)者,可能會(huì)對(duì) Vuex 和 Redux 間的差異表示關(guān)注,Redux 是 React 生態(tài)環(huán)境中最流行的 Flux 實(shí)現(xiàn)。Redux 事實(shí)上無(wú)法感知視圖層,所以它能夠輕松地通過(guò)一些簡(jiǎn)單綁定和 Vue 一起使用。Vuex 區(qū)別在于它是一個(gè)專(zhuān)門(mén)為 Vue 應(yīng)用所設(shè)計(jì)。這使得它能夠更好地和 Vue 進(jìn)行整合,同時(shí)提供簡(jiǎn)潔的 API 和更好的開(kāi)發(fā)體驗(yàn)。

這段話(huà)其實(shí)暴露了 Vuex 的一個(gè)缺陷,它和 Vue 強(qiáng)綁定,無(wú)法獨(dú)立存在,這種一些項(xiàng)目升級(jí)和遷移時(shí)會(huì)有很大的麻煩。Redux 作為 React 的狀態(tài)管理方案之一其實(shí)不依賴(lài)于 React。

React 周邊的狀態(tài)管理方案特別多,如 Redux、Mobx、Recoil 等,各有各的亮點(diǎn),其中使用最多的應(yīng)該是 Redux。

Vue 轉(zhuǎn) React 指南,看這篇文章就夠了

 

Redux 周邊生態(tài)也很豐富,可以更加下圖選擇不同的方案:

Vue 轉(zhuǎn) React 指南,看這篇文章就夠了

 

  • redux-thunk
  • redux-promise
  • redux-saga
  • redux-observable

由于這部分代碼較多,不詳細(xì)寫(xiě),不過(guò)如果你熟悉 Vuex 的概念,轉(zhuǎn)到 Redux 應(yīng)該不難。Vuex + axIOS 的做法和 Redux + redux-thunk 的寫(xiě)法類(lèi)似,不過(guò)現(xiàn)在 redux-saga 的方案被更多復(fù)雜項(xiàng)目采用,其中很重要的原因是 saga 的概念編寫(xiě)異步代碼非常優(yōu)雅,且能夠很好地解決靜態(tài)問(wèn)題(如果采用 Vuex + axios 的寫(xiě)法會(huì)異常復(fù)雜、冗長(zhǎng)),高度定制。

如果你要遷移 Vue 到 React,建議采用的方案是 Redux + saga,saga 的概念不是那么容易懂,學(xué)習(xí)需要一些時(shí)間,但當(dāng)你學(xué)會(huì)的時(shí)候就會(huì)明白這種寫(xiě)法比直接用 Promise 好太多了。

生命周期

Vue 的生命周期這里不再重復(fù),查詢(xún)官方文檔即可,React 生命周期如圖:

Vue 轉(zhuǎn) React 指南,看這篇文章就夠了

 

圖片可以在這里找到。一般情況下 class 寫(xiě)法主要用到 componentDidMount 和 componentWillUnmount 鉤子,React 的函數(shù)寫(xiě)法下可以用 useEffect 的執(zhí)行函數(shù)和清理函數(shù)去模擬 mount 和 unmount 過(guò)程:

import React, { useRef, useEffect } from 'react';

function Index() {
  const ref = useRef(null);
  
  useEffect(() => {
    console.log('mounted');

    return () => {
      console.log('will unmount');
    };
  }, []);

  return <input ref={ref}/>
}

export default Index;

useEffect 的原理這里不多說(shuō),可以看看相關(guān)文章:輕松學(xué)會(huì) React 鉤子:以 useEffect() 為例。其實(shí)從 React hook 中可以看到,React 在慢慢淡化生命周期的概念,減少自己對(duì)用戶(hù)代碼的侵入,將更多控制權(quán)交給用戶(hù)。

原生 DOM 操作

這部分 Vue 和 React 都是采用 ref 寫(xiě)法,Vue:

<template>
  <input ref="input" />
</template>

<script>
module.exports = {
  methods: {
    focusInput() {
      this.$refs.input.focus()
    }
  },
  mounted() {
    this.focusInput()
  }
}
</script>

React 寫(xiě)法:

import React, { useRef, useEffect } from 'react';

function Index() {
  const ref = useRef(null);
  
  useEffect(() => {
    ref.current?.focuse();
  }, []);

  return <input ref={ref}/>
}

export default Index;

useEffect 是 React hook,在依賴(lài)數(shù)組為空的時(shí)候效果類(lèi)似 componentDidMount 的生命周期函數(shù)(類(lèi)似 Vue 的 mounted)。此外 useRef 不止用在這里,也可以?huà)燧d一些其他的東東,實(shí)現(xiàn)一些復(fù)雜操作,比如 previousValue 和對(duì)象屬性等。

分享到:
標(biāo)簽:React
用戶(hù)無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定