react项目

一、React项目

1、项目依赖安装

脚手架:

解压两个文件:在项目的根目录下执行npm install////npm I  会按照package.json的配置安装依赖模块。

 

安装完成后,会出现一个node_modules,里面是安装的所有依赖的模块。

都是项目的根目录。

npm install

 

代理是哪里进去哪里出来。

 

2、项目整体说明

.babelrc: babel转译的配置文件。 (放的是预设值)环境信息,插件等。

.gitignore(忽略的信息)

Index.html(网页的HTML显示信息,发布的站点根目录)

Jsconfig.json(vscode自己所用的)

LICENSE()

.npmrc()  镜像库

Package.js(依赖信息)

README.md()

Src(js的插件信息)

  App.js

  Appstate.js

  Index.html

Node_moudles(npm包管理器设置以后所有的依赖文件)

Webpack.config.dev.js  开发时候使用的

Webpack.config.prod.js  生产环境使用的

 

3、配置文件详解

1)package.json

Npm 产生的文件,里面记录项目信息,所有项目依赖。

(1)版本信息:repository:

里面包括的是版本等信息。

 

(2)项目管理:scripts:

 

Start:启动webpack的dev server开发用的web server,提供的静态文件加载、自动刷新和热替换HMR(hot module replacement)

 

HMR可以在应用程序运行中替换,添加和删除模块,不需要重新加载模块,只是变化部分替换掉,不用HMR则自动刷新页面。

 

--HOT 启动HMR

--inline默认模式,使用HMR的时候建议使用inline模式,热替换时候会有消息显示在控制台。

 

Build使用webpack构建打包,对应npm run build

(3)项目依赖devdependencies

开发时候的依赖,不会打包到目标文件中。例如转译代码等。没必要到生产中去。

 

Dependencies运行的时候的依赖必须带到项目中去,

 

 

版本号:

指定安装版本号:

~安装指定中和最新的版本。

^安装指定中最高的版本,不低于指定的版本。*******建议常用

Latest:最新版本。

 

Babel转译的。

 

Css样式:

Css-loader样式表相关的模块。

 

React-hot-loader热加载插件。

 

运行时候的依赖:

 

 

 

 

Antd ant design基于react实现,后台管理较方便。

Axios 异步请求

Polyfiill解决浏览器api不支持的问题,磨平差异化。

React开发的主框架。

React-router路由

React-router-dom dom绑定路由

 

Mobx状态管理库,透明化

Mobx-react  mobx-react-devtools mobx和react结合的模块。

React和mobx是一个强强联合。

2)babel配置,.babelrc

Babel转译的配置文件

 

 

3)webpack配置

(1)webpack.config.dev.js

符合commonjs的模块。

Devtools:’source-map’

调试时候映射处理。

Entry入口:从入口直接找到需要打包的文件。

Output输出:

Resolve解析

Module模块

 

 

Test匹配条件的。

Exclude排除的,

Use使用模块的useentries列表中的loader,

Rules中.js结尾的但不在node_modules目录的文件使用转译babel-loader和热加载loader。

 

加载器:

style-loader通过<style>标签吧css添加到dom中。

Css-loader加载css

Less-loader对less的支持

 

Less:控制h2标记的。

 

 

 

 

Devserver,开发使用的server

 

Compress启动gzip

Port启动端口3000

Hot启动HMR

Proxy执行访问/api开头路径都代理到http://127.0.0.0:8080

4)vscode的配置

Jsconfig.json是vscode的配置文件,覆盖当前配置。

 

上面的配置文件,需要更改name,version,description,需要修改repository仓库地址,需要修改author、license信息。修改完成后,进行开发。

 

 

 

 

App-xxxxx的文档必须放在根目录,对于Windows下的是磁盘的根目录。

 

4、启动项目

npm start

 

 

二、react

1、简介

React是Facebook开发的并开源的前端框架。

2013年开源的,react解决的是前端的MVC框架中的view视图层的问题。

2、virtual dom***

DOM是什么?

DOM(文档对象模型document object model)

是HTML和xml文档,把其解析成为dom对象,展示成为树的模型。

Js在浏览器端多数情况下都是操作dom树的。

 

 

选择节点问题,通过id等进行查找等。

 

The document

 

 

The dom tree

 

 

将网页所有内容映射到一颗树形的结构的层级对象模型上,浏览器提供对dom支持,用户可以用脚本调用dom api来动态的修改dom节点,从而达到修改网页的目的,这种修改在浏览器中完成,浏览器胡根据dom的修改重绘dom的节点部分。

 

修改dom重新渲染的代价比较高,前端框架为了提高效率,尽量减少DOM的重绘,提出了virtual DOM,所有的修改都是现在的virtual dom上面完成,通过比较算法,找出浏览器和dom之间的差异,使用这个差异操作dom,浏览器只是需要渲染这个部分变化就行了。

 

React实现了dom diff算法可以高效比对vir dom和 dom的差异。

 

 

3、jsx的语法。

Jsx是一种Javascript和xml混写的语法,是Javascript的扩展。

直接插入HTML语句等。

 

 

4、测试程序

import React from 'react';

import ReactDOM from 'react-dom';

// import { render } from 'react-dom';

// import { AppContainer } from 'react-hot-loader';

// import AppState from './AppState';

// import App from './App';

 

// const appState = new AppState();

 

// render(

//   <AppContainer>

//     <App appState={appState} />

//   </AppContainer>,

//   document.getElementById('root')

// );

 

// if (module.hot) {

//   module.hot.accept('./App', () => { render(App) })

// }

 

class Root extends React.Component{

  render(){

    return <div>javascript excise</div>;

  }

}

 

ReactDOM.render(<Root/>,document.getElementById('root'));

 

Return的必须是jsx的语法。单标计必须是封口的。

Render()渲染函数,必须有return值,必须有顶级元素返回,所有元素必须闭合。

单行省略小括号,多好使用小括号。

 

class Root extends React.Component{

  render(){

    return <div>javascript <br/> excise</div>;

  }

}

 

 

<br/>换行符

 

 

 

 

 

 

 

 

class Root extends React.Component{

  render(){

    return React.createElement('div',null,'javascript');

    //return <div>javascript <br/> excise</div>;

  }

}

 

//ReactDOM.render(<Root/>,document.getElementById('root'));

ReactDom.render(React.createElement(Root),document.getElementById('root'));

 

 

 

更改属性的值:大括号等信息。

 

 

增加一个子元素:

class SubEle extends React.Component{

  render(){

    return <div>Sub content</div>

  }

}

 

class Root extends React.Component{

  render(){

    return (

      <div>

        <h2>welcome to study</h2>

        <br/>

        <SubEle/>

      </div>);

  }

}

 

ReactDOM.render(<Root/>,document.getElementById('root'))

 

 

 

React组件的render函数return,只能是一个顶级元素。

Jsx语法是XML,要求所有元素必须闭合,<br/>  不能是<br>

 

5、jsx规范

标签中首字母小写就是HTML标记,首字母大写就是组件。

要求严格的标记,要求所有标签必须闭合,br也应该写成<br  />,/前面留一个空格。

单行省略小括号,多行必须使用小括号。

元素有嵌套的,多行,缩进。

Jsx表达式:使用{}括起来,如果大括号内使用了引号,会当做字符串处理。

 

6、组件状态state

每一个react组件都有一个状态变量state,是一个JavaScript对象,为期定义属性保存值。

状态变化了,会出发UI重新渲染,使用setstate方法重新修改state的值。

State是组件内部使用的,是私有属性。

import React from 'react';

import ReactDOM from 'react-dom';

 

class Root extends React.Component{

  state = {

    p1: 'abc',

    p2:'.com'

  };

  render(){

    this.state.p1 = 'www.abc'

    return (

      <div>

        <div>welcome to {this.state.p1}{this.state.p2}</div>

        <br />

      </div>

    );

  }

 

}

 

ReactDOM.render(<Root />,document.getElementById('root'))

 

//this.state.p1 = 'www.abc'

改为下面的,不允许,不允许对更新中的state进行setState

    //this.setState({p1:'www.ab'})  //不允许这样修改,控制台会报错,

使用延时函数:setTimeout(里面是一个函数)   

setTimeout(()=>this.setState({p1:'www.abdd'}),5000)

 

 

class Root extends React.Component{

  state = {

    p1: 'abc',

    p2:'.com'

  };

  render(){

    //this.state.p1 = 'www.abc'

    //this.setState({p1:'www.ab'})  //不允许这样修改,控制台会报错,

    setTimeout(()=>this.setState({p1:'www.abdd'}),5000)

    return (

      <div>

        <div>welcome to {this.state.p1}{this.state.p2}</div>

        <br />

      </div>

    );s

  }

 

}

 

ReactDOM.render(<Root />,document.getElementById('root'))

 

 

7、复杂例子

 

Div的id是t1,鼠标按下事件就捆绑了一个函数,只要鼠标按下就会触发调用getEventTrigger函数,浏览器就会给其送一个参数event,event是时间对象,当时间触发的时候,event包含触发这个时间的对象。

8、HTML DOM的Javascript事件

属性

此事件发生在何时

Onabort

图像的加载被中断

Onblur

元素失去焦点

Onchange

域的内容被改变

Onclick

当用户点击某个对象时候调用的时间句柄

Ondbclick

当用户双击某个对象时候调用的事件句柄

Onerror

在加载文档或图像时候发生错误

Onfocus

元素获得焦点

Onkeydown

某个键盘键被按下

Onkeypress

某个键盘按键被按下并松开

Onkeyup

某个按键被松开

Onload

一张页面或一幅图像完成加载

Onmousedown

鼠标按钮被按下

Onmousemove

鼠标按键被移动

Onmouseout

鼠标从某元素移开

Onmouseover

鼠标移到某个元素之上

Onmouseup

鼠标按键被松开

Onreset

重置按钮被点击

Onresize

窗口或框架被重新调整大小

Onselect

文本被选中

Onsubmit

确认按钮被点击

Onunload

用户退出页面

 

import React from 'react';

import ReactDOM from 'react-dom';

class Toggle extends React.Component{

  state = {flag:true};

  handleClick(event){

    console.log(event.target.id)

    console.log(event.target === this);

    console.log(this)

    console.log(this.state)

    this.setState({flag:!this.state.flag})

  }

  render(){

    return <div id="t1" onClick={this.handleClick.bind(this)}>

    点击这句话,会触发一个事件1。{this.state.flag.toString()}

    </div>;

  }

}

 

class Root extends React.Component{

    state = {

    p1: 'abc',

    p2:'.com'

  };

  render(){

    //this.state.p1 = 'www.abc'

    //this.setState({p1:'www.ab'})  //不允许这样修改,控制台会报错,

    setTimeout(()=>this.setState({p1:'www.abdd'}),5000)

    return (

      <div>

        <div>welcome to {this.state.p1}{this.state.p2}</div>

        <br />

        <Toggle />

      </div>

    );

  }

}

 

ReactDOM.render(<Root />,document.getElementById('root'))

 

 

 

 

Toggle类

有自己的state属性,当render完成后,网页上有一个div标签捆绑了一个click事件的函数,div标签内有文本内容。

如果用过点击左键,就触发了click方法关联的handleClick函数,在这个函数里将状态值改变。

 

状态值state的改变将引发render重绘。

{this.handleClick.bind(this)},不能外加引号。

This.handleClick.bind(this)一定要绑定this,否则当触发捆绑的函数时候,this是函数执行的上下文决定的,this已经不是触发事件的对象了。

Console.log(event.target.id)取回的产生事件的对象的id,不是封装的组件的对象,所以,console.log(event.target===this)是false,这个this是通过绑定过来的。

 

React的事件:

使用小驼峰命名。

使用jsx表达式,表达式中要指定事件处理函数。

不能使用return false,如果要阻止事件默认行为,使用event.preventDefault()

 

Id是唯一的,坚决不能有重复的。

 

9、props

 

把react组件当做标签使用,可以为其增加属性:

 

组件之间利用state或者传parent传递参数

修改属性是不可以的,因为是只读的this.props.name.

 

import React from 'react';

import ReactDOM from 'react-dom';

 

class Toggle extends React.Component{

  state = {flag:true};

  handleClick(event){

    console.log(event.target.id)

    console.log(event.target === this);

    console.log(this)

    console.log(this.state)

    this.setState({flag:!this.state.flag})

  }

  render(){

    return <div id="t1" onClick={this.handleClick.bind(this)}>

    点击这句话,会触发一个事件1。{this.state.flag.toString()}

    {this.props.school}{this.props.age}

    <br />

    {this.props.parent.state.p1}

    {this.props.children}

    </div>;

  }

}

 

class Toggle1 extends React.Component{

  state = {flag:true};

  handleClick(event){

    console.log(event.target.id)

    console.log(event.target === this);

    console.log(this)

    console.log(this.state)

    this.setState({flag:!this.state.flag})

  }

  render(){

    return <div id="t2" onClick={this.handleClick.bind(this)}>

    点击这句话,会触发一个事件2。{this.state.flag.toString()}

    <br />

    {this.props.name}

    <hr />

    {this.props.age}

    {this.props.parent.state.p2}

    </div>;

  }

}

 

class Root extends React.Component{

    state = {

    p1: 'abc',

    p2:'.com'

  };

  render(){

    //this.state.p1 = 'www.abc'

    //this.setState({p1:'www.ab'})  //不允许这样修改,控制台会报错,

    setTimeout(()=>this.setState({p1:'www.abdd'}),5000)

    return (

      <div>

        <div>welcome to {this.state.p1}{this.state.p2}</div>

        <br />

        <Toggle school='abc' age= '20' parent={this} >

        </Toggle>

        <Toggle1 name='tom' age= '10' parent={this}/>

      </div>

    );

  }

}

 

ReactDOM.render(<Root />,document.getElementById('root'))

注意访问parent送进去的是this,访问实例本身的属性的方式是利用this.props.state.p1的值

 

 

 

10、构造器

利用construc(props)。

Super()调用父类的。

只要extends的,必须利用super()调用。Props作为参数传入。

import React from 'react';

import ReactDOM from 'react-dom';

 

class Toggle extends React.Component{

  constructor(props){

    console.log('Toggle')

    super(props)

    this.state = {flag:true};

  }

 

  handleClick(event){

    console.log(event.target.id)

    console.log(event.target === this);

    console.log(this)

    console.log(this.state)

    this.setState({flag:!this.state.flag})

  }

  render(){

    return <div id="t1" onClick={this.handleClick.bind(this)}>

    点击这句话,会触发一个事件1。{this.state.flag.toString()}

    {this.props.school}{this.props.age}

    <br />

    {this.props.parent.state.p1}

    {this.props.children}

    </div>;

  }

}

 

class Toggle1 extends React.Component{

  constructor(props){

    console.log('Toggle1')

    super(props)

    this.state = {flag:true};

  }

 

  handleClick(event){

    console.log(event.target.id)

    console.log(event.target === this);

    console.log(this)

    console.log(this.state)

    this.setState({flag:!this.state.flag})

  }

  render(){

    return <div id="t2" onClick={this.handleClick.bind(this)}>

    点击这句话,会触发一个事件2。{this.state.flag.toString()}

    <br />

    {this.props.name}

    <hr />

    {this.props.age}

    {this.props.parent.state.p2}

    </div>;

  }

}

 

class Root extends React.Component{

    state = {

    p1: 'abc',

    p2:'.com'

  };

  render(){

    //this.state.p1 = 'www.abc'

    //this.setState({p1:'www.ab'})  //不允许这样修改,控制台会报错,

    setTimeout(()=>this.setState({p1:'www.abdd'}),5000)

    return (

      <div>

        <div>welcome to {this.state.p1}{this.state.p2}</div>

        <br />

        <Toggle school='abc' age= '20' parent={this} >

        </Toggle>

        <Toggle1 name='tom' age= '10' parent={this}/>

      </div>

    );

  }

}

 

ReactDOM.render(<Root />,document.getElementById('root'))

 

 

 

 

11、组件的生命周期

组件的声明周期可分为三个状态。

Mounting:已插入真实dom。

Updating:正在被重新渲染。

Unmounting:已移除真实dom。

 

方法如下:

(1)装载组件触发:

Componentwillmount在渲染前调用,在客户端也在服务器端,指挥在装载前调用一次。

Componentdidmount:在第一次渲染后调用,只要是在客户端,之后的组件已经生成对应的dom结构,可以通过this.getdomnode()来进行访问, 想与其他的Javascript框架一起使用,在这个方法中调用setTimeout,setinterval或者发送ajax请求等操作,只是在装载完后调用一次,在render之后。

(2)更新组件触发,这些方法不会再首次render组件的周期调用。

Componentwillreceiveprops(nextprops)在组件接受到一个新的prop时候被调用,在初始化render时候不会调用。

Shouldcomponentupdae(nextprops,nextstate)返回布尔值,在组件接受到新的Props或者state时候被调用,在初始化或者使用forceupdate时候不被调用。(如果设置为false,就不允许更新组件。)

Componentwillupdate(nextprops,nextstate)在组件接受到新的props或者state还没render时候被调用,在初始化不会调用。

Componentdidupdate(prevprops,prevstate)在组件完成后更新后立即调用,在初始化时候不会被调用。

(3)卸载组件触发

ComponentwillUNmount在组件从dom中移除的时候立即被调用

 

 

图中,constructor构造器是最早执行的函数,触发更新生命周期的函数,需要更新state或者props。

 

import React from 'react';

import ReactDOM from 'react-dom';

 

class Sub extends React.Component{

  constructor(props){

    console.log('sub con')

    super(props)

    this.state = {count:0}

  }

  handleClick(event){

    this.setState({count:this.state.count + 1});

  }

  render(){

    console.log('sub render')

    return <div id='sub'onClick={this.handleClick.bind(this)}>

    Sub's count = {this.state.count}

    </ div>

  }  

  componentWillMount(){

    //第一次render之前

    console.log('sub componentwillmount')

  }

  componentDidMount(){

    //第一次render之后

    console.log('sub componentDidMount')

  }

 

  componentWillUnmount(){

    //清理工作

    console.log('sub componentWillUnmount ')

  }

}

 

class Root extends React.Component{

  constructor(props){

    console.log('root con')

    super(props)

    this.state = {}

  }

  render(){

    return <div>

        <Sub  />

        </ div>

  }

}

 

ReactDOM.render(<Root />,document.getElementById('root'))

 

 

 

顺序是constructor  =》 componentwillmount =》 render =》 componentdidmount –state或props改变,render。

 

import React from 'react';

import ReactDOM from 'react-dom';

import { ENGINE_METHOD_DIGESTS } from 'constants';

 

class Sub extends React.Component{

  constructor(props){

    console.log('sub con')

    super(props)

    this.state = {count:0}

  }

  handleClick(event){

    this.setState({count:this.count + 1});

  }

  render(){

    console.log('sub render')

    return <div id='sub'onClick={this.handleClick.bind(this)}>

    Sub's count = {this.state.count}

    <a style={{height:200+'px',color:'red',backgroundColor:'#f0f0f0'}} >

    </ a>

 

    </ div>

  }  

  componentWillMount(){

    //第一次render之前

    console.log('sub componentwillmount')

  }

  componentDidMount(){

    //第一次render之后

    console.log('sub componentDidMount')

  }

 

  componentWillUnmount(){

    //清理工作

    console.log('sub componentWillUnmount ')

  }

  componentWillReceiveProps(nextProps){

    //props变更时候,接受新的props,交给shouldComponentUpdate

    //props组件内只读,只能从外部改变

 

    console.log(this.props)

    console.log(nextProps)

    console.log('sub componentWillReceiveProps',this.state.count);

  }

 

  shouldComponentUpdate(nextProps,nextState){

    //是否组件更新,props或state方式改变时候,返回布尔值,true才会更新

    console.log('sub shouldComponentUpdate',this.state.count,nextState)

    return true

  }

  componentWillUpdate(nextProps,nextState){

    //同意更新后,真正更新之前,调用render

    console.log('sub componentWillUpdate',this.state.count,nextState)

  }

  componentDidUpdate(prevProps,prevState){

    //同意更新后,真正更新后,在render之后调用。

    console.log('sub componentDidUpdate',this.state.count,prevState)

  }

}

 

class Root extends React.Component{

  constructor(props){

    console.log('root con')

    super(props)

    this.state = {}

  }

  render(){

    return <div>

        <Sub  />

        </ div>

  }

}

 

ReactDOM.render(<Root />,document.getElementById('root'))

 

 

 

Componentwillmount第一次装载,在首次render之前,例如控制state、props。

Componentdidmount第一次装载结束,在首次render之后,控制state,props。

Componentwillreceiveprops在组件内部,props是只读不可变的,这个函数接受到新的props,可以对props做一些处理,this.props={name:‘root’}这就是偷梁换柱,componentwillreceiveprops触发,也会走shouldcomponentupdate。

Shouldcomponentupdate判断是否需要组件更新,是否render,精确的控制渲染,提高性能。

Componentwillupdate除了首次render之外,每次render前执行,componentdidupdate在render之后调用。

 

componentWillMount(){

    //第一次render之前

    console.log('sub componentwillmount')

  }

  componentDidMount(){

    //第一次render之后

    console.log('sub componentDidMount')

  }

 

  componentWillUnmount(){

    //清理工作

    console.log('sub componentWillUnmount ')

  }

  componentWillReceiveProps(nextProps){

    //props变更时候,接受新的props,交给shouldComponentUpdate

    //props组件内只读,只能从外部改变

 

    console.log(this.props)

    console.log(nextProps)

    console.log('sub componentWillReceiveProps',this.state.count);

  }

 

  shouldComponentUpdate(nextProps,nextState){

    //是否组件更新,props或state方式改变时候,返回布尔值,true才会更新

    console.log('sub shouldComponentUpdate',this.state.count,nextState)

    return true

  }

  componentWillUpdate(nextProps,nextState){

    //同意更新后,真正更新之前,调用render

    console.log('sub componentWillUpdate',this.state.count,nextState)

  }

  componentDidUpdate(prevProps,prevState){

    //同意更新后,真正更新后,在render之后调用。

    console.log('sub componentDidUpdate',this.state.count,prevState)

  }

}

 

 

 

12、无状态组件

也叫做函数式组件。

许多时候组件简单不需要state状态,也不需要声明周期函数,无条件组件很好的满足了需要,无状态组件提供了一个参数props,返回一个react元素,无状态组件函数本身就是render函数。

 

import React from 'react';

import ReactDOM from 'react-dom';

 

//let Root = props =><div>{props.shoolname}</div>;

 

//ReactDOM.render(<Root shoolname='abc' />,document.getElementById('root'))

 

function Root(props){

  return <div> {props.name}</div>

}

 

ReactDOM.render(<Root name='bcd'/>,document.getElementById('root'))

 

 

 

 

三、高阶组件

 

1、柯里化

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = function (Component){

  function _wrapper(props){

    return (

      <div>

        {props.name}

        <hr />

        <Component />

      </ div>

    )

  }

  return _wrapper

}

 

let Root = props =><div>Root</ div>

 

let NeeComp = wrapper(Root)

 

ReactDOM.render(<NeeComp name='abc' />,document.getElementById('root'))

 

 

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = function (Component){

  return props=>(

      <div>

        {props.name}

        <hr />

        <Component />

      </ div>

    )

}

 

let Root = props =><div>Root</ div>

 

let NeeComp = wrapper(Root)

 

ReactDOM.render(<NeeComp name='abc' />,document.getElementById('root'))

 

 

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = Component=> props =>(

      <div>

        {props.name}

        <hr />

        <Component />

      </ div>

    )

 

let Root = props =><div>Root</ div>

 

let NeeComp = wrapper(Root)

 

ReactDOM.render(<NeeComp name='abc' />,document.getElementById('root'))

 

 

2、装饰器

 

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = Component=>props=>

 

  (<div>

    {props.aname}

    <hr />

    <Component />

    </ div>

  )

 

 

   //let Root = props => <div>Root</ div>

 

@wrapper

class Root extends React.Component{

  render(){

    return <div> Root</ div>

  }

}

 

let Newarpper = wrapper(Root)

 

ReactDOM.render(<Newarpper aname='abc' />,document.getElementById('root'))

 

 

 

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = Components=>props=>

 

  (<div>

    {props.aname}

    <hr />

    <Components {...props} />

    </ div>

  )

 

 

   //let Root = props => <div>Root</ div>

 

@wrapper

class Root extends React.Component{

  render(){

    return <div> Root{this.props.aname}</ div>

  }

}

 

 //let Newarpper = wrapper(Root)

 

ReactDOM.render(<Root aname='abc' />,document.getElementById('root'))

 

 

Root中也显示props.name的属性,使用  <Components {...props} />

增加属性等。

 

 

import React from 'react';

import ReactDOM from 'react-dom';

 

let wrapper = id => Components=>props=>

 

  (<div id = {id}>

    {props.aname}

    <hr />

    <Components {...props} />

    </ div>

  )

 

 

   //let Root = props => <div>Root</ div>

 

@wrapper('wrapper')

class Root extends React.Component{

  render(){

    return <div> Root{this.props.aname}</ div>

  }

}

 

 //let Newarpper = wrapper(Root)

 

ReactDOM.render(<Root aname='abc' />,document.getElementById('root'))

 

 

 

 

 

 

 

 

 

函数后面不能加括号调用,因为加括号返回的不是组件,而是render函数需要的内容。

要求返回的是组件,组件函数。

 

posted @ 2018-11-12 23:40  Python爱好者666  阅读(1288)  评论(0编辑  收藏  举报