createElement是JSX被转载得到的,在 React中用来创建 React元素(即虚拟DOM)的内容。cloneElement用于复制元素并传递新的 props。
redux 是一个应用数据流框架,主要解决了组件之间状态共享问题,原理是集中式管理,主要有三个核心方法:action store reduce
工作流程
view 调用store的dispatch 接受action传入的store,reduce进行state操作
view通过store提供的getState获取最新的数据
redux的优点:
新增的state 对状态的管理更加明确
流程更加规范,减少手动编写代码,提高编码效率
redux的缺点:
当数据更新是有时候组件不需要,也要重新绘制,影响效率
function withLoginAuth(WrappedComponent) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
isLogin: false
};
}
async componentDidMount() {
const isLogin = await getLoginStatus();
this.setState({ isLogin });
}
render() {
if (this.state.isLogin) {
return <WrappedComponent {...this.props} />;
}
return (<div>您还未登录...</div>);
}
}
}
shouldComponentUpdate
这个方法用来判断是否需要调用render方法重新描绘dom。因为dom的描绘非常消耗性能,如果我们能在shouldComponentUpdate方
法中能够写出更优化的dom diff
算法,可以极大的提高性能
reconciliation
)的过程。和解(reconciliation
)的最终目标是以最有效的方式,根据这个新的状态来更新UI
。 为此,React
将构建一个新的 React
元素树(您可以将其视为 UI
的对象表示)通过这样做, React 将会知道发生的确切变化,并且通过了解发生什么变化,只需在绝对必要的情况下进行更新即可最小化 UI 的占用空间
state
呢 ?如果试图直接更新 state
,则不会重新渲染组件。
// 错误
This.state.message = 'Hello world';
需要使用setState()
方法来更新 state
。它调度对组件state
对象的更新。当state
改变时,组件通过重新渲染来响应:
// 正确做法
This.setState({message: ‘Hello World’});
store
并维持状态props
,并将组件自身渲染到页面时,该组件就是一个 ‘无状态组件(stateless component)’,可以使用一个纯函数来创建这样的组件。这种组件也被称为哑组件(dumb components)或展示组件参考:前端react面试题详细解答
使用了装饰模式,高阶组件的运用:
function withWindowWidth(BaseComponent) {
class DerivedClass extends React.Component {
state = {
windowWidth: window.innerWidth,
}
onResize = () => {
this.setState({
windowWidth: window.innerWidth,
})
}
componentDidMount() {
window.addEventListener('resize', this.onResize)
}
componentWillUnmount() {
window.removeEventListener('resize', this.onResize);
}
render() {
return <BaseComponent {...this.props} {...this.state}/>
}
}
return DerivedClass;
}
const MyComponent = (props) => {
return <div>Window width is: {props.windowWidth}</div>
};
export default withWindowWidth(MyComponent);
装饰模式的特点是不需要改变 被装饰对象 本身,而只是在外面套一个外壳接口。JavaScript 目前已经有了原生装饰器的提案,其用法如下:
@testable
class MyTestableClass {
}
Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。在开发过程中,我们需要保证某个元素的 key 在其同级元素中具有唯一性。
在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染此外,React 还需要借助 Key 值来判断元素与本地状态的关联关系。
注意事项:
Context 通过组件树提供了一个传递数据的方法,从而避免了在每一个层级手动的传递 props 属性。
import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
class Header extends Component{
render() {
return (
<div>
<Title/>
</div>
)
}
}
class Title extends Component{
static contextTypes={
color:PropTypes.string
}
render() {
return (
<div style={{color:this.context.color}}>
Title
</div>
)
}
}
class Main extends Component{
render() {
return (
<div>
<Content>
</Content>
</div>
)
}
}
class Content extends Component{
static contextTypes={
color: PropTypes.string,
changeColor:PropTypes.func
}
render() {
return (
<div style={{color:this.context.color}}>
Content
<button onClick={()=>this.context.changeColor('green')}>绿色</button>
<button onClick={()=>this.context.changeColor('orange')}>橙色</button>
</div>
)
}
}
class Page extends Component{
constructor() {
super();
this.state={color:'red'};
}
static childContextTypes={
color: PropTypes.string,
changeColor:PropTypes.func
}
getChildContext() {
return {
color: this.state.color,
changeColor:(color)=>{
this.setState({color})
}
}
}
render() {
return (
<div>
<Header/>
<Main/>
</div>
)
}
}
ReactDOM.render(<Page/>,document.querySelector('#root'));
Flux
的最大特点,就是数据的"单向流动"。
View
View
发出用户的 Action
Dispatcher
收到Action
,要求 Store
进行相应的更新Store
更新后,发出一个"change"
事件View
收到"change"
事件后,更新页面这个问题就设计到了数据持久化, 主要的实现方式有以下几种:
pushState
函数可以给历史记录关联一个任意的可序列化 state
,所以可以在路由 push
的时候将当前页面的一些信息存到 state
中,下次返回到这个页面的时候就能从 state
里面取出离开前的数据重新渲染。react-router 直接可以支持。这个方法适合一些需要临时存储的场景。
Keys
是React
用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识
key
在其同级元素中具有唯一性。在 React Diff
算法中React
会借助元素的 Key
值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。此外,React 还需要借助 Key
值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中 Key
的重要性通常,使用 Webpack的 DefinePlugin方法将 NODE ENV设置为 production。这将剥离 propType验证和额外的警告。除此之外,还可以减少代码,因为 React使用 Uglify的dead-code来消除开发代码和注释,这将大大减少包占用的空间。
在开发过程中,我们需要保证某个元素的 key 在其同级元素中具有唯一性。在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素,从而减少不必要的元素重渲染。此外,React 还需要借助 Key 值来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中 Key 的重要性。
答:componentWillMount componentDidMount render
高阶组件不是组件,是 增强函数,可以输入一个元组件,返回出一个新的增强组件
function proxyHoc(WrappedComponent) {
return class extends React.Component {
render() {
const newProps = {
count: 1
}
return <WrappedComponent {...this.props} {...newProps} />
}
}
}
const MyContainer = (WrappedComponent)=>{
return class extends WrappedComponent {
render(){
return super.render();
}
}
}