JSX就是Javascript和XML結合的一種格式,要使用須要在babelrc裏配置, Babel 轉譯器會把 JSX 轉換成一個名爲 React.createElement() 的方法調用react
// 最外層必須有一個元素包裹 <div>hello world!</div> // 屬性都要駝峯 <div className="haha" ></div> // 樣式 <div style={{ marginTop: '10px'}}></div> // 變量 <div> {user.name }</div> // 事件 <button onClick={}> click me </button> // 遍歷 <ul> { list.map( ({name, value}) => <li key={name} value={value}>{name}</li> ) } </ul> // 展開對象 const props = {name: "tom" } <div {...props}></div>
a. 虛擬DOM(Virtual DOM)機制:對於每個組件,React會在內存中構建一個相對應的DOM樹,基於React開發時全部的DOM構造都是經過虛擬DOM進行,每當組件的狀態發生變化時,React都會從新構建整個DOM數據,而後將當前的整個DOM樹和上一次的DOM樹進行對比,得出DOM結構變化的部分(Patchs),而後將這些Patchs 再更新到真實DOM中
b. 兩個不一樣類型的元素會產生不一樣的樹(根元素不一樣結構樹必定不一樣)
c. 開發者能夠經過key屬性指定不一樣樹中沒有發生改變的子元素
d. diff算法的核心就是同級比較android
// 默認參數 Main.defaultProps = { list: [ ] } // setState 是異步的 this.setState( (prevState,props) => ({ text: prev.text + "-ha" }))
Note: 父子組件的掛載順序,更新順序ios
forEach map filter some reduce ,setTimeout setInterval等算法
顧名思義,它沒有state,接收props,它是一種只負責展現的純組件 使用函數式的方式聲明,會使得代碼的可讀性更好,並能大大減小代碼量,多寫無狀態組件編程
function HelloComponent(props) { return <div>Hello {props.name}</div> } ReactDOM.render(<HelloComponent name="marlon" />, mountNode)
7 使用 fragment 碎片
Jsx 要求返回的元素,必須有東西包裹,使用碎片能夠減小一層DOM數組
<React.Fragment> <td>Hello</td> <td>World</td> </React.Fragment> // 能夠簡寫爲 <> <td>Hello</td> <td>World</td> </>
Context 經過組件樹提供了一個傳遞數據的方法,從而避免了在每個層級手動的傳遞 props 屬性,React.createContext 建立一個context,一個context包含provider(數據提供者), comsumer(數據消費者), Provider 有一個value參數,用來覆蓋建立時的默認值babel
// 建立一個 theme Context, 默認 theme 的值爲 light const ThemeContext = React.createContext ('light'); function ThemedButton(props) { // ThemedButton 組件從 context 接收 theme return ( <ThemeContext.Consumer> {theme => <Button {...props} theme={theme} />} </ThemeContext.Consumer> ); } // 中間組件 function Toolbar(props) { return ( <div> <ThemedButton /> </div> ); } class App extends React.Component { render() { return ( <ThemeContext.Provider value="dark"> <Toolbar /> </ThemeContext.Provider> ); } }
推薦一個react模塊的目錄結構react-router
/states 狀態 /(widgets|components)各種組件、彈窗等 index.js index.less service 建議放在config裏,全局統一 Computed用於生成計算數據,autorun相似用來監聽某一數據改變而做出反映 import {action, observable ,autorun} from 'mobx'; import StateAdd from "./add" class State { constructor(){ this.$add = new StateAdd(this); } // 顯示 @observable show = false; // query @observable query = { trade: null, type: 1 } /** * @name 獲取列表 */ @action getList = () => { } } const instance = new State(); autorun(() => { if(instance.show){ console.log("打開彈窗了") } }) export default instance
主要有兩種實現方式屬性proxy、繼承實現
一般使用裝飾器模式調用,常見的有mobx的 @observer, react-router的withRouter等less
------ 屬性proxy 實現以下 import React from "react" export default class extends React.Component { render = () => <div> <div> <Hoc1_text name={'Hoc1_text'}/> </div> <div> <Hoc2_text /> </div> </div> } class Text1 extends React.Component { render = () => <div> this is simple text <br/> {this.props.name} </div> } /** * @name 操做props */ function Hoc1(Component){ return class extends React.Component { render = () => <div className='hoc1'> <Component {...Object.assign({} , this.props, {gen : '111'})}/> </div> } } const Hoc1_text = Hoc1(Text1); class Text2 extends React.Component { render = () => <div> <input type="text" value={this.props.value} onChange={this.props.change}/> </div> } /** *@name 抽離state */ function Hoc2(Component){ return class extends React.Component { state = { value: '11' } change = e => { this.setState({ value: e.target.value }) } render = () => <div> <Component value={this.state.value} change={this.change}/> </div> } } const Hoc2_text = Hoc2(Text2); function Hoc3(Component){ return class extends React.Component { getRef = _ref => { this.refs = _ref; } render = () => <div> <Component ref={this.getRef}/> </div> } } ------ 繼承組件 實現以下 ------- class Text extends React.Component { render(){ return ( <div> this is text </div> ) } } // 生命週期能夠覆蓋掉 const hoc2 = Component => { return class NewHoc extends Component { static displayName = `NewHoc-${Component.displayName || Component.name}` render(){ const element= super.render(); console.log(element) const style = { color: element.type === 'div' ? 'red' : 'green' } const newProps = {...this.props, style} return React.cloneElement(element, newProps, element.props.children) } } } const NewCom = hoc2(Text)