1. 程式人生 > >react一些些

react一些些

1.react component有幾種寫法?各有什麼特點

① 函式式定義的無狀態元件(Stateless Functional)

效能更高效、程式碼更簡潔
沒有 state,也就是無狀態
不需要管理/維護 元件的生命週期
純函式,相同的 props 會得到同樣的UI渲染結果
元件不會被例項化,整體渲染效能得到提升
元件不能訪問this物件

②.
ES5原生方式React.createClass定義的元件
是react剛開始推薦的建立元件的方式,這是ES5的原生的JavaScript來實現的React元件
是建立有狀態的元件
些元件是要被例項化的,並且可以訪問元件的生命週期方法
建立的元件,其每一個成員函式的this都有React自動繫結

③.ES6 方式定義的元件(Class Components)
ES6的形式來建立react的元件的,是React目前極為推薦的建立有狀態元件的方式
建立的元件,其成員函式不會自動繫結this,需要開發者手動繫結,否則this不能獲取當前元件例項物件
有三種手動繫結方法:可以在建構函式中完成繫結,也可以在呼叫時使用method.bind(this)來完成繫結,還可以使用arrow function來繫結

2.寫個受控表單元件更新state的流程?

class App extends Component {
        constructor(props) {
            super(props)
            this.state = { value: 'hi' }
        }
        
        onInputChange = (e) => {
            this.setState({ value: e.target.value })
        }
        
        render() {
            const { value } = this.state
            return (
                <input value={value} onChange={this.onInputChange} />
            )
        }
    }

文字描述
1.初始化state設定表單的預設值,例如 this.state = { value: 'hi' }
2.每當表單值發生變化時,呼叫onChange事件
3.通過物件e拿到改變的狀態,例如e.target.value
4.通過setState更新應用value 並 觸發檢視重新渲染,最終完成表單元件的更新

3下面兩種寫法的得到的this.state.text值是一樣嗎?為什麼?

...
    this.state = { text : '這是一個栗子' }
    ...

    // 使用傳遞物件的寫法
    handleClick = () => {
        this.setState({ text: this.state.text + '111' })
        this.setState({ text: this.state.text + '222' })
    }
    
    // 使用傳遞函式的寫法
    handleClick = () => {
        this.setState((prevState) => {
            return { text: prevState.text + '111' }
        })
        this.setState((prevState) => {
            return { text: prevState.text + '222' }
        })
    }

    render() {
        return <div onClick={this.handleClick}>{this.state.text}</div>
    }

兩種傳遞方式,得到的結果是不一樣的。

傳遞物件 => this.state.text => '這是一個栗子222'
傳遞函式 => this.state.text => '這是一個栗子111222'

setState為了提升效能,在批量執行 state 改變在做統一的DOM渲染。而在這個批量執行的過程中,如果你多次傳遞的是一堆物件,它就會做一些物件合併或者組合的操作,例如Object.assign({}, { a: '111' }, { a: '222' })。如果key值一樣的話,後面的值會覆蓋掉前面的值。
但多次傳遞函式方式,每次 React 從 setState 執行函式,並通過傳遞已更新的狀態來更新你的狀態。這使得功能 setState 可以基於先前狀態設定狀態。

4.為什麼我們利用迴圈產生的元件中要用上key這個特殊的prop?

render() {
        return (
            <ul>
                list.map((item, index) => {
                    return <li key={item.id}>{item.name} - {item.age}</li>
                })
            </ul>
        )
    }

5.keys 是 React 用於追蹤哪些列表中元素被修改、被新增或者被移除的輔助標識
之所以需要key,因為react 是非常高效的,它會藉助元素的 key 值來判斷該元素是新建立的,或者移動(交換位置)而來的,從而減少不必要的元素重渲染

如果上面程式碼改成 key={index} 呢,有啥區別

這樣做的效率是非常非常非常低的,只有list變化了, 每個元素對應的key都變了,react Virtual DOM就不論有沒有相同的項,更新都會重新渲染了。所以我們要保證某個元素的 key 在其同級元素中具有唯一性, 這個key 的值可以直接後臺資料返回的 id

6.react元件間的通訊有哪些

  1. 父元件向子元件通訊
    react 中資料是單向傳遞的,父元件可以向子元件通過傳 props 的方式,
    子元件拿到 props 之後做相應的處理

2.子元件向父元件通訊
子元件向父元件傳遞資料(通訊) 也是要通過 props 傳遞一個函式,子元件呼叫這個函式,並將子元件需要傳遞的資料作為引數,傳遞給父元件

3.兄弟元件之間通訊
可以通過他們的共同父元件來實現,

7.跨n級元件之間通訊或者,非巢狀元件的通訊有什麼好的辦法

  1. 利用 react 提供的 context , 它類似一個全域性大容器,我們把想傳遞的資訊放在裡面,需要的往裡面取便是
    2.自定義事件的方式。自定義事件是典型的釋出/訂閱模式,通過向事件物件上新增監聽器和觸發事件來實現元件間通訊
    3.狀態管理工具 mobx redux 等

8.簡要說說React中虛擬DOM原理

在React中,也有一個render函式來將虛擬DOM樹,並且,React中有state轉移的過程,所以每次state有變化之後,就會觸發render函式,重新構造一個虛擬DOM樹。對比新舊虛擬DOM樹的差別,記錄下差異,然後只針對差異部分對應的真實DOM進行操作。
如何進行新舊虛擬DOM樹的對比呢?
這裡採用的是Diff演算法。Diff演算法比較複雜,主要的思路是這樣的。
首先,每一次生成的虛擬DOM樹上的各個節點都對應唯一的一個id,當第二次生成了新的DOM樹時,對原來樹上的每一個節點對比新樹上對應節點,如果不同,就記錄下來這個差異。同時,差異也分為很多種:

替換節點;
修改屬性;
對文字內容修改
移動、刪除、增加節點;
比如,替換節點就需要調原生JS的repaceChild()介面;
對於修改屬性,則要調setAttribute()介面等等。



作者:水落斜陽
連結:https://www.jianshu.com/p/4fb47009c330
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。