虛擬DOM(VDOM)是真實DOM的內存表示。將整個UI結構保持在內存中並和真正的DOM結構保持同步。在調用渲染函數和元素展示在屏幕上之間有一個處理過程,這個過程叫作reconciliation
。javascript
虛擬DOM的工做過程分爲三個階段:
1)每當任意一個底層數據發生更改時,整個UI都將在虛擬DOM表示中從新渲染
2)對比固然的虛擬DOM和上一份虛擬DOM的不一樣之處
3)對比結束以後,真是DOM就會根據對比結果從新渲染變化的DOM節點java
Shadow DOM 在網絡平臺中引入做用域樣式。 無需工具或命名約定,您便可使用原生 JavaScript 捆綁 CSS 和標記、隱藏實現詳情以及編寫獨立的組件。
Shadow DOM 與普通 DOM 相同,但有兩點區別:1) 建立/使用的方式;2) 與頁面其餘部分有關的行爲方式。 一般,您建立 DOM 節點並將其附加至其餘元素做爲子項。 藉助於 shadow DOM,您能夠建立做用域 DOM 樹,該 DOM 樹附加至該元素上,但與其自身真正的子項分離開來。這一做用域子樹稱爲影子樹。被附着的元素稱爲影子宿主。 您在影子中添加的任何項均將成爲宿主元素的本地項,包括 <style>
。 這就是 shadow DOM 實現 CSS 樣式做用域的方式。
因此,Shadow DOM是一種瀏覽器技術,主要用於在web組件中肯定變量和CSS的範圍。虛擬DOM是一個由JavaScript中的庫在瀏覽器api之上實現的概念。react
你可使用refs
直接訪問一個元素節點或者組件實例。要使用這個屬性,您須要向組件添加一個ref屬性,該屬性的值是一個回調函數,它將接收底層DOM元素或組件實例做爲其第一個參數。webpack
class UnControlledForm extends Component {
handleSubmit = () => {
console.log("Input Value: ", this.input.value)
}
render () {
return (
<form onSubmit={this.handleSubmit}>
<input
type='text'
ref={(input) => this.input = input} />
<button type='submit'>Submit</button>
</form>
)
}
}
複製代碼
能夠看到,在input
標籤上有一個ref
屬性,給它賦值了一個函數方法。這個方法接收了input
的真實DOM元素,接着咱們將在handleSubmit方法裏面訪問它。
一般認爲只能在類組件中使用refs
,但你也但是利用閉包在方法組件中使用。web
function CustomForm ({handleSubmit}) {
let inputElement
return (
<form onSubmit={() => handleSubmit(inputElement.value)}>
<input
type='text'
ref={(input) => inputElement = input} />
<button type='submit'>Submit</button>
</form>
)
}
複製代碼
還有另一種使用refs
的方法。你能夠用React.createRef()
方法建立refs
並經過ref
屬性綁定到元素上。爲了在整個組件中使用ref,只需將ref分配給構造函數中的實例屬性。編程
class MyComponent extends React.Component {
constructor(props) {
super(props)
this.myRef = React.createRef()
}
render() {
return <div ref={this.myRef} />
}
}
複製代碼
Ref forwarding 是一個性質,它容許組件接收一個ref
屬性,並將這個屬性傳遞給子組件。api
const ButtonElement = React.forwardRef((props, ref) => (
<button ref={ref} className="CustomButton">
{props.children}
</button>
));
// Create ref to the DOM button:
const ref = React.createRef();
<ButtonElement ref={ref}>{'Forward Ref'}</ButtonElement>
複製代碼
爲了解決跨瀏覽器兼容性問題,React中的事件處理中將傳遞SyntheticEvent的實例,SyntheticEvent是React中包裝了各類瀏覽器原生屬性的跨瀏覽器包裝器。它暴露出統一的事件接口,保證在不一樣瀏覽器上都可以正常運行。
稍微有趣的是,React實際上並無將事件附加到子節點自己。而是使用事件代理的方式,React使用一個事件偵聽器在頂層偵聽全部事件。這有助於提升性能,也意味着React在更新DOM時沒必要擔憂跟蹤事件偵聽器被移除。數組
props和state都是純JavaScript對象。雖然它們都包含影響渲染輸出的信息,但它們在組件方面的功能不一樣。好比:瀏覽器
高階組件(HOC)就是一個方法,它接收一個組件並返回一個新的組件。這是一種由React的組成性質衍生出來的模式。
也能夠成爲「純組件」,由於它們能夠接受任何動態提供的子組件,但不會修改或複製其輸入組件中的任何行爲。
HOC 能夠用在不少狀況下,好比:網絡
一個子類的構造器在調用sper
方法以前是不能使用this
引用的。就行ES6中的sub-classes。將props參數傳遞給super()調用的主要緣由是訪問子構造函數中的this.props。
props
class MyComponent extends React.Component {
constructor(props) {
super(props);
console.log(this.props); // Prints { name: 'sudheer',age: 30 }
}
}
複製代碼
props
class MyComponent extends React.Component {
constructor(props) {
super();
console.log(this.props); // Prints undefined
// But Props parameter is still available
console.log(props); // Prints { name: 'sudheer',age: 30 }
}
render() {
// No difference outside constructor
console.log(this.props) // Prints { name: 'sudheer',age: 30 }
}
}
複製代碼
上面的代碼片斷能夠看出,this.props行爲僅在構造函數中不一樣,構造函數以外的表現都是同樣的。
在HTML中,表單元素<input>
、<select>
以及<textarea>
等,都維護本身的狀態並根據用戶輸入進行更新。當用戶提交表單時,上述元素的值將隨表單一塊兒發送。但在React中,並非這樣的,包含表單的組件將跟蹤處於其狀態中的<input>
的值,並在每次啓動回調函數(例如onChange)時,由於狀態將被更新而從新渲染該組件。
一個輸入表單元素,其值以這種方式由React控制,稱爲受控組件。
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
複製代碼
Answer:
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
複製代碼
當facebook第一次向人們介紹react時,也介紹了一種新的JavaScript寫法,也就是 JSX,它將HTML模版寫在javascrit代碼中。JSX自己是沒法被瀏覽器識別的,它必須藉助bable或者webpack編譯成傳統的javascrit。儘管解一開始許多開發人員下意識的反對這種寫法,但JSX(與ES2015一塊兒)已經成爲定義React組件的肯定方法。
class MyComponent extends React.Component {
render() {
let props = this.props;
return (
<div className="my-component">
<a href={props.url}>{props.name}</a>
</div>
);
}
}
複製代碼
代碼以下:
class MyComponent extends React.Component {
constructor(props) {
// set the default internal state
this.state = {
clicks: 0
};
}
componentDidMount() {
this.refs.myComponentDiv.addEventListener('click', this.clickHandler);
}
componentWillUnmount() {
this.refs.myComponentDiv.removeEventListener('click', this.clickHandler);
}
clickHandler() {
this.setState({
clicks: this.clicks + 1
});
}
render() {
let children = this.props.children;
return (
<div className="my-component" ref="myComponentDiv">
<h2>My Component ({this.state.clicks} clicks})</h2>
<h3>{this.props.headerText}</h3>
{children}
</div>
);
}
}
複製代碼
Answer:
props
傳給supr()
constructor(props) {
super(props);
// ...
}
複製代碼
constructor(props) {
super(props);
this.clickHandler = this.clickHandler.bind(this);
// ...
}
複製代碼
React組件的生命週期有四個不一樣的階段:
props
以及更新state
。包括shouldComponentUpdate
, componentWillUpdate
以及 componentDidUpdate
三個生命週期方法。componentWillUnmount
方法。prop
更新引發state
變化時觸發。true
。若是你確認組件在state
或者prop
變化以後不須要更新,那麼你能夠返回false
。由於你能夠在組件接收到一個新的prop的時候阻止組件的從新渲染,這對於提升組件性能是一種很好的方式。props
或者state
發生變化以及shouldComponentUpdate
返回爲true
,那麼在組件從新渲染以前就會觸發此方法。React Hooks時在React 16.8新增的性質。它的的意思是,組件儘可能寫成純函數,若是須要外部功能和反作用,就用鉤子把外部代碼"鉤"進來。
它容許你不須要寫一個類,就可使用react的狀態和其它性質。經過Hooks,您能夠從組件中提取有狀態邏輯,這樣就能夠獨立測試並重用它。Hooks容許您重用有狀態邏輯,而無需更改組件層次結構。這使得在許多組件之間鉤子變得很容易。
在Hooks出現以前,咱們寫一個簡單的組件都要建立一個類,在大型複雜的項目中每每很複雜。最終致使:
React Hooks 的設計目的,就是增強版函數組件,徹底不使用"類",就能寫出一個全功能的組件。
一般, hooks可以提取和重用狀態邏輯,這種邏輯在多個組件之間是通用的,而不須要高階組件或渲染props來實現。hooks可以輕鬆地操做功能組件的狀態,而無需將它們轉換爲類組件。
Hooks在類組件裏面不起做用。經過使用它,咱們能夠避免使用componentDidMount
, componentDidUpdate
, componentWillUnmount
這些生命週期方法。但須要使用例如useffect
這樣的內置鉤子。
...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...
const setCount = () => {
setCounter(count + 1);
setMoreStuff(...);
...
};
複製代碼
useState
是react hooks的一個內置方法。useState(0)返回一個元組,其中第一個參數count是計數器的當前狀態,setCounter是容許咱們更新計數器狀態的方法。
咱們可使用setCounter方法在任何地方更新count的狀態。這裏,咱們在setCount函數中使用它,在這裏咱們能夠作更多的事情;hooks的思想是,咱們可使代碼更具功能性,並在非必要的狀況下避免基於類的組件。
傳統的MVC框架很好的將數據 (Model), UI (View) 以及 邏輯 (Controller) 分離開,但它仍然面臨兩個問題:
Flux模式使得複雜組件不須要再經過級聯更新的方式渲染組件。每一個組件均可以經過store提供的數據維護本身的狀態。Flux模式還經過限制對共享數據的直接訪問來加強數據的統一管理。