虚拟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模式还经过限制对共享数据的直接访问来加强数据的统一管理。