入手react項(xiàng)目三個(gè)月的心得( 純干貨 )

本篇文章并不是按照官網(wǎng)API由易到難講解,而是按照我所做的項(xiàng)目實(shí)踐得出的結(jié)論靖苇。可能有些寫的并不是絕對(duì)的完美的方案班缰,我們可以一起討論贤壁,并且我也是在學(xué)習(xí)當(dāng)中〔和可能有自己遇到的一些坑的一些解決方案脾拆,希望能在工作中幫助到大家??。
React基本概念還是需要看下官網(wǎng)API莹妒,了解并熟知React的語(yǔ)法概念和組件化思想名船,生命周期要熟悉。ES6常用特性要熟悉旨怠。
看身邊的同事渠驼,意識(shí)到不一定是前端可以學(xué)會(huì)React,如果你會(huì)其他語(yǔ)言鉴腻,同樣也能入門迷扇。
關(guān)于React腳手架 create-react-app 安裝配置我在另一篇幅有講:http://www.reibang.com/p/b168c47a7620

React是什么?

React是一個(gè)聲明式爽哎,高效且靈活的用于構(gòu)建用戶界面的JavaScript庫(kù)谋梭。使用React可以將一些簡(jiǎn)短、獨(dú)立的代碼片段組合成復(fù)雜的UI界面倦青,這些代碼片段被稱作“組件”瓮床。

class HelloWorld extends Component {
    //初始化組件狀態(tài)
    constructor(props) {
        super(props)
        this.state = {
            loading: false
        }
    }
  componentDidMount(){
      //調(diào)用API
  }
  render() {
        return <div>hello world!</div>
    }
}
export default HelloWorld

由此看出以上是一個(gè)簡(jiǎn)單的組件,this.state是對(duì)狀態(tài)的一個(gè)初始化賦值的概念。它是一個(gè)有狀態(tài)的組件隘庄,具有完整的生命周期概念踢步。但項(xiàng)目中不僅僅是只用這種有狀態(tài)組件,還有其他組件類型丑掺。
無(wú)狀態(tài)組件是通過(guò)無(wú)狀態(tài)的函數(shù)創(chuàng)建的获印,它是一種只負(fù)責(zé)展示的純組件。無(wú)狀態(tài)組件的特點(diǎn)是不需要管理組件狀態(tài)state街州,數(shù)據(jù)直接通過(guò)props傳入即可兼丰,這也符合React單向數(shù)據(jù)流的思想。
這里可以科普下無(wú)狀態(tài)組件的概念:

無(wú)狀態(tài)組件

無(wú)狀態(tài)組件可以通過(guò)減少繼承Component而來(lái)的生命周期函數(shù)而達(dá)到性能優(yōu)化的效果唆缴。從本質(zhì)上來(lái)說(shuō)鳍征,無(wú)狀態(tài)組件就是一個(gè)單純的render函數(shù),所以無(wú)狀態(tài)組件的缺點(diǎn)也是顯而易見(jiàn)的面徽。因?yàn)樗鼪](méi)有shouldComponentUpdate生命周期函數(shù)艳丛,所以每次state更新,它都會(huì)重新繪制render函數(shù)趟紊。

對(duì)于無(wú)狀態(tài)組件的函數(shù)式生命方法氮双,不僅可以提高代碼的可閱讀行,還能大大的減少代碼量霎匈,提高代碼的復(fù)用率戴差。

以下是我項(xiàng)目中所寫的無(wú)狀態(tài)組件。

const ScaleScorePage = (props) => {
    const patientScales = props.patientStatus.get('newScales')
    return (
        <div className={styles.commonDiagnosisWrapper}>
            <div className={styles.commonDiagnosisTitle}>
                <h3>卒中嚴(yán)重程度評(píng)估</h3>
            </div>
            {patientScales &&
            <div className={styles.commonDiagnosisInner}>
                <Row>
                    {renderBaseScoreInner(patientScales)}
                </Row>
            </div>
            }
            <div className={styles["text-right"]} style={{display: 'none'}}><Button>查看出院時(shí)量表評(píng)分</Button></div>
        </div>
    )
}
export default ScaleScorePage

以上代碼中props是父組件傳遞過(guò)來(lái)的屬性铛嘱。此時(shí)就用到了父組件如何向子組件通信暖释,父組件通過(guò)props給子組件傳遞數(shù)據(jù)。如下示例:

<ScaleScorePage patientStatus={patientStatus}/>

上面的patientStatus就是屬性值通過(guò)props傳遞給子組件ScaleScorePage弄痹。

思考:如何在這種無(wú)狀態(tài)組件中想用到生命周期的概念呢?這個(gè)就要用到React 16.8的新增特性Hook,它可以讓你在不編寫class的情況下使用state以及其他的React特性嵌器。

Hook

最近項(xiàng)目中用到的示例:
主要用到的就是 useState ,以及 useEffect

import React, { useEffect, useState } from "react"
import {Button} from 'antd';
import {connect} from "react-redux";
import styles from '../../css/diagnosis/diagnosis.module.css'
import {getPatientComplaint} from "../../actions";
const PatientStatement = (props) => {
    const {patientID,patientComplaint} = props
    const [basePatientDetails, onPatientStatementChange] = useState(false)
    useEffect(() =>{props.getPatientComplaint(patientID)},[])
    return (
        <div className={styles.commonDiagnosisWrapper}>
            <div className={`${styles.commonDiagnosisTitle} ${styles.commonDiagnosisTitle1}`}>
                <h3>主訴</h3>
                <Button style={{display: 'none'}} type="primary" key="ignore" onClick={()=>onPatientStatementChange(!basePatientDetails)}>
                    {basePatientDetails ? '保存' : '編輯'}
                </Button>
                <span style={{float: 'right'}}>記錄時(shí)間: 暫無(wú)</span>
            </div>
            <ul>
                {patientComplaint.map((item,idx)=><li key={item.id}>{item}</li>)}
            </ul>
        </div>
    )
}

const mapStateToProps = state => {
    return {
        patientComplaint: state.diagnosis.get('patientComplaint')
    }
}
export default connect(mapStateToProps,{getPatientComplaint})(PatientStatement)

由以上get的知識(shí)點(diǎn)的涵蓋面可能有點(diǎn)多肛真,首先可以忽略redux這部分內(nèi)容,這個(gè)可以單獨(dú)幾個(gè)篇幅去講解爽航。如何從父組件向子組件傳遞值上面已經(jīng)講過(guò)蚓让,下面就是講解useState.

useState
// 聲明一個(gè)叫做basePatientDetails的 state 變量,
 const [basePatientDetails, onPatientStatementChange] = useState(false)

聲明一個(gè)叫做basePatientDetails的 state 變量讥珍,初始化值設(shè)置為false历极,并且在onPatientStatementChange方法中改變state變量的值。

useEffect

Effect Hook 可以讓你在函數(shù)組件中執(zhí)行副作用操作衷佃。如果你熟悉React class的生命周期趟卸,你可以把useEffect 看作是componentDidMount , componentDidUpdate和componentWillUnmount這三個(gè)函數(shù)的組合。

useEffect(() ={ props.getPatientComplaint(patientID) } )     //xxxx
useEffect(() ={ props.getPatientComplaint(patientID) },[] )     

??注意:以上寫法是有個(gè)箭頭函數(shù),然后執(zhí)行了一個(gè)API接口調(diào)用锄列。因?yàn)樗哂猩芷诘母拍钔荚疲@樣又陷入萬(wàn)惡的循環(huán)中,所以解決辦法是在結(jié)尾加 [].

css樣式模塊化

另外在樣式上邻邮,最開(kāi)始寫項(xiàng)目的時(shí)候竣况,發(fā)現(xiàn)引用的css樣式是全局的樣式,會(huì)經(jīng)常出現(xiàn)樣式覆蓋問(wèn)題筒严。這樣對(duì)于團(tuán)隊(duì)開(kāi)發(fā)是非常不友好的丹泉。后來(lái)在項(xiàng)目中對(duì)css起的名字做了研究,xxx.module.css這樣自動(dòng)對(duì)css樣式進(jìn)行模塊化管理鸭蛙。只需要在組件引用的時(shí)候使用

//如果引用多個(gè)樣式文件
import styles from '../../css/diagnosis/diagnosis.module.css'
import iStyles from '../../css/infomation.module.css'

使用時(shí)候這樣用,以下有單個(gè)類名以及多個(gè)類名示例:

<div className={styles.outer}> 
 <div className={`${styles.inner} ${iStyles.border}`}>
</div> 
解構(gòu)賦值

const { patientID,patientComplaint } = props
//等價(jià)于
const patientID = props.patientID
const patientComplaint = props.patientComplaint

列表 & key

map方法非常實(shí)用摹恨。


<ul>
  {patientComplaint.map((item,idx)=><li key={item.id}>{item}</li>)}
</ul>

由此map方法使用前提必須是一個(gè)數(shù)組,參數(shù)( currentValue, index, arr )规惰。
currentValue (必須睬塌。當(dāng)前元素的值)
index (可選。當(dāng)前元素的索引值)
arr (可選歇万。當(dāng)前元素屬于的數(shù)組對(duì)象)

另外:還會(huì)有數(shù)據(jù)改造的情況(出現(xiàn)于后臺(tái)字段跟前端所用字段不一致)


const renderExamTitle = (item) => {
    return <Fragment><span>{item.examItem||''}</span><span style={{float: 'right'}}>{item.examUnit||''}</span></Fragment>
}
const renderExamResult = (item, params, style1) => {
    return <Fragment><span style={style1}>{item.examResult?item.examResult:'無(wú)'} {params}</span></Fragment>
}
/**處理數(shù)值變化值*/
const handlerExamResult = (item) => {
    switch (item.examStatus) {
        case 'u':
            return renderExamResult(item, '↑', {color: '#d90f0f'})
        case 'd':
            return renderExamResult(item, '↓', {color: '#d90f0f'})
        default:
            return renderExamResult(item, '');
    }
}
const handlerBody = (data) => {
    // 接口數(shù)據(jù)映射處理
    return data.map((item, index) =>({
        key: index,
        examItem: renderExamTitle(item),
        examResult: handlerExamResult(item),
        maleStd: item.maleStd
   
    }))
}

思考??:
假設(shè)如果后臺(tái)給的數(shù)據(jù)是長(zhǎng)得這個(gè)樣子揩晴,需要前端頁(yè)面進(jìn)行循環(huán)處理結(jié)構(gòu)。

const options = {
"正程盎牵或近乎正常": "0-1分",
"輕度卒中/小卒中": "2-4分",
"中度卒中": "5-15分",
"中-重度卒中": "16-20分",
"重度卒中": "21-42分"}

提示??:

console.log( Object.keys(options) )
//expected output: ["正沉蚶迹或近乎正常", "輕度卒中/小卒中", "中度卒中", "中-重度卒中", "重度卒中"]

console.log( Object.values(options) )
//exoected output: ["0-1分", "2-4分", "5-15分", "16-20分", "21-42分"]

由此你是不是有思路了。get it ??寒锚!


<ul className={styles.scaleScoreText}>
  {Object.keys(options).map((itm, idx) => <li key={idx}>{options[itm]}<p>{itm}</p></li>)}
</ul>

React 中的三元運(yùn)算符

如果在jsx語(yǔ)句中用到if-else 語(yǔ)句進(jìn)行條件渲染怎么辦劫映?可以使用三元運(yùn)算符:

{
  nodeDetails.isFinal?
    <div>有數(shù)據(jù) </div> : <div>暫無(wú)結(jié)果</div>
}
<div>參考范圍 {item.range=== null?'暫無(wú)':item.range}</div>

如果只返回條件渲染的一方面,可以使用&&運(yùn)算符

{
data.checks.length>0 &&<div>顯示....</div>
}

補(bǔ)充:
1.let arr = ['a','b','c'] 改造成===> obj = {a:1,b:1,c:1}

let arr = ['a','b','c'] 
let obj = {}
arr.map(item=>obj[item] = 1)
console.log(obj)

未完待續(xù)刹前。泳赋。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喇喉,一起剝皮案震驚了整個(gè)濱河市祖今,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拣技,老刑警劉巖千诬,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異膏斤,居然都是意外死亡徐绑,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門莫辨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)傲茄,“玉大人毅访,你說(shuō)我怎么就攤上這事√棠唬” “怎么了俺抽?”我有些...
    開(kāi)封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)较曼。 經(jīng)常有香客問(wèn)我磷斧,道長(zhǎng),這世上最難降的妖魔是什么捷犹? 我笑而不...
    開(kāi)封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任弛饭,我火速辦了婚禮,結(jié)果婚禮上萍歉,老公的妹妹穿的比我還像新娘侣颂。我一直安慰自己,他們只是感情好枪孩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布憔晒。 她就那樣靜靜地躺著,像睡著了一般蔑舞。 火紅的嫁衣襯著肌膚如雪拒担。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天攻询,我揣著相機(jī)與錄音从撼,去河邊找鬼。 笑死钧栖,一個(gè)胖子當(dāng)著我的面吹牛低零,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拯杠,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼掏婶,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了潭陪?” 一聲冷哼從身側(cè)響起雄妥,我...
    開(kāi)封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎畔咧,沒(méi)想到半個(gè)月后茎芭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體揖膜,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡誓沸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了壹粟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拜隧。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宿百,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出洪添,到底是詐尸還是另有隱情垦页,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布干奢,位于F島的核電站痊焊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏忿峻。R本人自食惡果不足惜薄啥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望逛尚。 院中可真熱鬧垄惧,春花似錦、人聲如沸绰寞。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)滤钱。三九已至觉壶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間菩暗,已是汗流浹背掰曾。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留停团,地道東北人旷坦。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像佑稠,于是被迫代替她去往敵國(guó)和親秒梅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容