React

react 2013 單向數(shù)據(jù)流
和vue區(qū)別
內(nèi)存的改變影響頁(yè)面的改變,不管頁(yè)面的改變, 影響內(nèi)存的改變
自己處理頁(yè)面的改變, 影響內(nèi)存, 通過(guò)事件, 調(diào)用函數(shù), 通知根據(jù)內(nèi)存對(duì)象改變頁(yè)面
沒(méi)有指令

安裝React腳手架: npm install -g create-react-app
創(chuàng)建腳手架: create-react-app myApp
產(chǎn)看版本: create-react-app --version

安裝react-router: cnpm i react-router -S
安裝react-router-dom: cnpm i react-router-dom -S
安裝redux: cnpm i redux

展示配置文件: npm run eject
使用sass: npm i node-sass

有變化的屬性
className
htmlFor
style={{ fontSize: '12px' }}

this.state: 讀取狀態(tài)
this.setState: 更新組件的狀態(tài)

import React, { Component } from 'react' //創(chuàng)建組件、虛擬DOM元素, 生命周期
import ReactDOM from 'react-dom' //把創(chuàng)建好的 組件 和 虛擬DOM放到頁(yè)面上面展示

創(chuàng)建虛擬DOM元素
// 參數(shù)1: 創(chuàng)建的元素的類(lèi)型, 字符串, 表示元素的名稱(chēng)
// 參數(shù)2: 是一個(gè)對(duì)象或 null, 表示 當(dāng)前這個(gè) DOM 元素的屬性
// 參數(shù)3: 子節(jié)點(diǎn) (包括 其他 虛擬DOM 獲取 文本子節(jié)點(diǎn))
// 參數(shù)n: 其它子節(jié)點(diǎn)
const myh1 = React.createElement('h1',{title:"this is a h1", id: "myh1"},'這是一個(gè)標(biāo)題H1')

使用 ReactDOM 把虛擬 DOM 渲染到頁(yè)面上
// 參數(shù)1: 要渲染的那個(gè)虛擬DOM元素
// 參數(shù)2: 指定頁(yè)面上一個(gè)容器
ReactDOM.render(myh1, document.getElementById("app"))

class關(guān)鍵字創(chuàng)建組件
class Movie extends React.Component{
//render 函數(shù)的作用, 是 渲染 當(dāng)前組件所對(duì)應(yīng)的 虛擬DOM元素
render() {
return (
<div>這是Movie組件</div>
)
}
}
##const Footer = ()=>{
return (
)
}

Ref選取dom元素
<input type="text" ref="id"/> ref ==> this.refs.id.value
<input type="text" ref="id=>this.id = id" /> this.id.value

限定接收props類(lèi)型
TodoList.propTypes = {
title: PropTypes.number.isRequired //必須傳遞此屬性
}
array ==> bool ==> func ==> number ==> object ==> string ==> symbol
指定屬性默認(rèn)值
Person.defaultProps = {
sex: '男',
age: 18
}
父?jìng)髯?
組件接收屬性值的傳遞:
this.props屬性名
例如:
<Header title="留言"> <div>這是我的children</div> </Header>
constructor(props){
super(props)
render(){
return(
{this.props.title}
{this.props.children}
)
}
}

子傳父:
在父組件中定義一個(gè)設(shè)置state的方法, 然后把這個(gè)方法通過(guò)屬性傳遞給子組件
在子組件中調(diào)用這個(gè)方法。 把值傳入就可以了。

路由react-router-dom: exact精確匹配
安裝: cnpm i react-router-dom -S
引入: import { BrowserRouter,HashRouter, Route, Link, NavLink, Switch, Redirect, useParams } from 'react-router-dom';
代碼:
<Router>
<div>
<switch> //匹配到第一個(gè)終止匹配
<Route exact path="/home" component={Home} />
<Route exact path="/kind" component={Kind} />
<Route exact path="/user" component={User} />
<Redirect from="/" to="/home" /> //跟目錄跳轉(zhuǎn)home頁(yè)面
<Route exact path="/404" component={404}> //配置404頁(yè)面
<Redirect from="/*" to="/" /> //重定向404頁(yè)面
</switch>
</div>
</Router>
react路由懶加載
yarn add react-loadable
import Loadable from 'react-loadable';
編程跳轉(zhuǎn)
指定前進(jìn)后退: this.props.history.go()
后退: this.props.history.goBack()
前進(jìn): this.props.history.goForward()

    this.props.history.push('/Home');
    query傳參
        this.props.history.push({ pathName:'/Home', search:'id=id&name=name' })
    
params動(dòng)態(tài)路由傳參:
    跳轉(zhuǎn)傳參:  <NavLink to="/detail/paramName" activeClassName="navActive"></NavLink>
    路由配置:  <Route path="/detail/:paramName" component={Detail} />
    組件參數(shù)接收:  this.props.match.params.paramName
    
query動(dòng)態(tài)路由傳參:
    跳轉(zhuǎn)傳參:  <NavLink to={{pathName:"/detail",search:"?id=123&name=tian"}} activeClassName="navActive"></NavLink>
    路由配置:  <Route path="/detail" component={Detail} />
    組件參數(shù)接收:  this.props.location.search
    ① 此時(shí)拿到是一個(gè)字符串 'id=1&name=2'
        需要安裝 
            npm i query-string
        使用
            import queryString from 'query-string';
    queryString.parse( this.props.location.search )

redux
安裝 npm i redux
配置
index.js文件下
import { createStore } from 'redux';
import reducer from './reducer.js'
const store = createStore(reducer);
export default store;
reducer.js文件下
const defaultState = {
list: [1,2,3,4,5]
}
export default (state=defaultState, action) => {
return state
}
獲取state:
import store from './store.js'
store.getState().list;
訂閱state改變: //每次派發(fā)action的時(shí)候重新獲取數(shù)據(jù)
store.subscribe(this.handleSubScribe)
觸發(fā)對(duì)應(yīng)事件改變state
handleSubScribe = ()=>{
this.setState({
initState = store.getState().initState;
})
}
更新state:
const action = {
type: "CHANGE_VALUE",
value: '新的value'
};
store.dispatch(action)
在reducer.js文件下
export default (state=defaultState, action) => {
if(action.type == 'CHANGE_VALUE'){
const initState = {...state};
initState.value = action.value;
return initState;
}
return state
}
模塊化:
reducer.js文件下
import {combineReducers} from 'redux';
import homeReducer from './modules/homeReducer'
import userReducer from './modules/userReducer'
let reducer = combineReducers({
home: homeReducer,
user: userReducer
})
export default reducer
homeReducer.js文件下 || userReducer.js文件下
const defaultState = {
list: [1,2,3,4,5]
}
export default (state=defaultState, action) => {
return state
}
獲取:
store.getState().home.value
訂閱:
store.subscribe(this.handleSubScribe);
handleSubScribe = () => {
this.setState({
value: store.getState().home.value
})
}
更新state:
const action = {
type: "CHANGE_VALUE",
value: '新的value'
};
store.dispatch(action)
在homeReducer.js文件下
export default (state=defaultState, action) => {
if(action.type == 'CHANGE_VALUE'){
const initState = {...state};
initState.value = action.value;
return initState;
}
return state
}
react-redux
安裝:
cnpm i react-redux
APP.js文件內(nèi)
import store from './store/index.js'
所有組件使用 ** 包裹
<Provider store={store}></Provider>

    頁(yè)面內(nèi)使用:
        const mapStateToProps = state => {
          return {
            name: state.home.name
          }
        }
        const mapDispatchToProps = dispatch => {
          return {
            changeName(){
              dispatch({
                type:'CHANGE_NAME',
                value:'田國(guó)元'
              })
            }
          }
        }
        export default connect(reduxState, reduxAction)(Home);
redux-thunk
    安裝:
        cnpm i redux-thunk
    store文件下index.js
        import { createStore,compose,applyMiddleware } from 'redux';
        import reducer from './reducer.js'
        import thunk from 'redux-thunk'
        const store = createStore(reducer,compose(applyMiddleware(thunk)));
        export default store;
    頁(yè)面內(nèi): ## redux-thunk異步請(qǐng)求解決了redux的action只能是對(duì)象, 可以讓對(duì)象形式改成為異步函數(shù),異步函數(shù)接收dispatch
        const reduxAction = dispatch => {
          return {
            changeName(){
            dispatch(dispatchs => {
                fetch('./data.json').then(res=>res.json()).then(data=>{
                  console.log(data);
                  dispatchs({
                    type:'CHANGE_NAME',
                    value: data.id
                  })
                })
              })
            }
          }
        }

React生命周期
getDefaultProps 初始化prop屬性 (es6的寫(xiě)法中被刪除)
getInitialState 初始化當(dāng)前狀態(tài) (es6的寫(xiě)法中被刪除)
**componentWillMount 組件初始化前 (即將進(jìn)入dom)
**componentDidMount 組件初始化DOM插入完后 (已經(jīng)進(jìn)入dom)
**render 觸發(fā)state改變UI

componentWillReceiveProps 父組件傳遞調(diào)用方法
shouldComponentUpdata 是否要更新 return false 就不會(huì)更新

componentWillUpdate 組件更新之前
componentDidUpdate 組件更新之后
componentWillUnmount 組件銷(xiāo)毀前
componentDidUnmount 組件銷(xiāo)毀后

注意點(diǎn):
1. XML 基本語(yǔ)法
定義標(biāo)簽是, 只允許被一個(gè)標(biāo)簽包裹
標(biāo)簽一定要閉合
2. 元素類(lèi)型
小寫(xiě)首字母對(duì)應(yīng) DOM 元素屬性
大寫(xiě)首字母對(duì)應(yīng)組件元素
注釋使用 js 注釋方法
3. 元素屬性
class 屬性改為 className
for 屬性改為 htmlFor
Boolean 屬性: 省略 Boolean 屬性值會(huì)導(dǎo)致 JSX 認(rèn)為 bool 值設(shè)為了 true
4. JavaScript 屬性表達(dá)式
屬性只要使用表達(dá)式, 只要用 {} 替換 "" 即可
<input type="text" value={ val ? val : "" } />
5. HTML 轉(zhuǎn)義
React會(huì)將所有要顯示到 DOM 的字符串轉(zhuǎn)義, 放置 XSS.
后臺(tái)傳過(guò)來(lái)的數(shù)據(jù)帶頁(yè)面標(biāo)簽的是不能直接轉(zhuǎn)義的, 集體轉(zhuǎn)移的寫(xiě)法如下:
var content= ' <strong> content </strong> ';
React.render(
<div dangerouslySetInnerHTML = {{__html: content}}> </div>,
document.body
)

動(dòng)畫(huà): ReactCSSTransitionGroup
1. 引入組件
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
2.使用ReactCSSTransitionGroup 標(biāo)簽包裹動(dòng)畫(huà)標(biāo)簽
<ReactCSSTransitionGroup
transitionName='example'
transitionEnterTimeout={500}
transitionLeaveTimeout={300}
>
</ReactCSSTransitionGroup>
注意:
生成{items}的時(shí)候, 里面沒(méi)一個(gè)元素必須包含KEY屬性。 因?yàn)閞eact 要判斷哪個(gè)元素進(jìn)入, 停留, 移除

    css: {
        .example-enter  // 進(jìn)入動(dòng)畫(huà)的起點(diǎn)
        .example-enter-active  // 進(jìn)入動(dòng)畫(huà)的終點(diǎn)
        .example-leave  // 離開(kāi)動(dòng)畫(huà)的起點(diǎn)
        .example-leave-active  // 離開(kāi)動(dòng)畫(huà)的終點(diǎn)
        
        .example-enter{ margin-left: -200px; transform:rotate(0deg); transition-duration:500ms; }
        .example-enter-active{ margin-left: 0px; transform:rotate(3600deg); }
        .example-leave{ margin-left:0px; opacity:1; transition-duration:300ms; }
        .example-leave-active{ margin-left:600px; opacity:0; }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容