React中创建组件

1.第一种创建组件的方式

使用构造函数来创建组件,如果要接收外界传递的数据,需要在构造函数的参数列表中使用props来接收;

必须要向外return一个合法的JSX创建的虚拟DOM

创建组件:

注意:组件首字母必须要大写,否则就会被当作一个普通标签来渲染,浏览器就识别不了报错

function Hello(){
    //如果在一个组件中return一个null,则表示此组件是空的,什么都不会渲染
    //return null;
    //在组件中必须返回一个jsx虚拟DOM元素
   
    return <div>这是function创建的Hello组件</div> }

为组件传递数据:

const dog = {
    name:'大黄',
    age: 3,
    gender: '雄'
}

// ...为展开运算符,将dog里的属性全部展开,即...dog就相当于
name={dog.name} age={dog.age} gender={dog.gender}
ReactDOM.render(<div>
   {/*直接把组件的名称以标签的形式丢到页面上即可 */}
   {/* <Hello name={dog.name} age={dog.age} gender={dog.gender}></Hello> */}
   <Hello {...dog}></Hello>     
   </div>,document.getElementById('app'));

//在构造函数中接受外界传递过来的数据
function Hello(props){
    //结论:不论是vue还是React,组件中的props永远都是只读的,不能被重新赋值
    //props.name = 'zs';    //报错
    return <div>这是function创建的Hello组件 -- {props.name} --{props.age} --{props.gender}</div> }

 以上代码都是写在同一个js文件里,实际上我们开发为了保持代码的简洁性,会将组件封装到单独的文件中:

创建一个Hello.jsx的文件:

import React from 'react'

//创建并导出组件
export default function Hello(props){
    //如果在一个组件中return一个null,则表示此组件是空的,什么都不会渲染
    //return null;
    //在组件中必须返回一个jsx虚拟DOM元素
    console.log(props);
    //结论:不论是vue还是React,组件中的props永远都是只读的,不能被重新赋值
    //props.name = 'zs';    //报错
    return <div>这是function创建的Hello组件 -- {props.name} --{props.age} --{props.gender}</div> }

在其他文件里导入组件:

//导入Hello组件
//默认如果不做单独的配置的话,不能省略.jsx后缀名
import Hello from './components/Hello.jsx'

如果想要省略后缀名,需要在webpack.config.js文件中添加配置:

resolve: {
        extensions: ['.js','.jsx', '.json']  //表示这几个文件的后缀名,可以省略不写,顺序从左到右
    }

 导入组件时,配置和使用@路径符号:

resolve: {
        extensions: ['.js','.jsx', '.json'],  //表示这几个文件的后缀名,可以省略不写,顺序从左到右
        alias: {   //表示别名
            '@': path.join(__dirname,'./src')
        }
    }
//注意:这里的@符号表示项目根目录中的src这一层目录
import Hello from '@/components/Hello'

 


 2.第二种创建组件的方式: 基于class关键字创建组件

组件的基本结构:

//如果要使用class定义组件,必须要让自己的组件继承React.Component
class 组件名称 extends React.Component{
   //在组件内部,必须有render函数
   render(){
      //render函数中必须返回合法的JSX虚拟DOM结构
      return <div>这是class创建的组件</div>
   }
}

 创建组件:

//class关键字创建组件
class Movie extends React.Component{
   //由于Movie组件继承了React.Component,所以自定义的构造其中必须调用super()
   constructor(){
      super();
   }

   //render函数的作用是渲染当前组件所对应的虚拟DOM元素
   //render是实例方法
   render(){
      return <div>
         这是Movie组件 
         </div>
   }
}

为组件传递数据:

const user = {
   name: '张三',
   age: 22,
   gender: '男'
}

//class关键字创建组件
class Movie extends React.Component{
   //由于Movie组件继承了React.Component,所以自定义的构造其中必须调用super()
   constructor(){
      super();
   }

   //render函数的作用是渲染当前组件所对应的虚拟DOM元素
   //render是实例方法
   render(){
      //注意:不管是用function创建组件还是使用class创建组件,props属性都是只读的
      //this.props.name = '李四';  //报错
    
      //在class关键字创建组件中,如果想使用外界传递过来的props参数,不需要接收,直接通过this.props.***访问
      return <div>
         {/*在class组件内部,this表示当前组件的实例对象 */}
         这是Movie组件 -- {this.props.name} -- {this.props.age} -- {this.props.gender}
         </div>
   }
}

ReactDOM.render(<div>
   {/*这里的Movie标签其实就是Movie类的一个实例对象 */}
   <Movie {...user}></Movie>
   </div>,document.getElementById('app'));

class关键字创建的组件的私有属性state:

//class关键字创建组件
class Movie extends React.Component{
   //由于Movie组件继承了React.Component,所以自定义的构造其中必须调用super()
   constructor(){
      super();
      //只有调用了super()以后才能使用this关键字
      // this.state = {}相当于Vue中的data() {return {}}
      this.state = {
         msg: '大家好,我是class创建的Movie组件'
      };
   }

   //render函数的作用是渲染当前组件所对应的虚拟DOM元素
   render(){  
      //state里面的数据是可读可写的
      this.state.msg = 'msg的值被我修改了';

      return <div>
         {/*在class组件内部,this表示当前组件的实例对象 */}
         这是Movie组件
         <h3>{this.state.msg}</h3>
         </div>
   }
}

ReactDOM.render(<div>
   {/*这里的Movie标签其实就是Movie类的一个实例对象 */}
   <Movie></Movie>
   </div>,document.getElementById('app'));

 


 3.两种创建组件方式的对比

 注意:使用class关键字创建的组件有自己的私有数据和生命周期函数;

            但是使用function创建的组件只有props,没有自己的私有数据和生命周期

(1)用构造函数创建出来的组件叫做“无状态组件

(2)用class关键字创建出来的组件叫做“有状态组件

(3)什么情况下使用有状态组件?什么情况下使用无状态组件?

  如果一个组件需要有自己的私有数据,则推荐使用有状态组件

  如果一个组件不需要有自己的私有数据,则推荐使用无状态组件

  无状态组件由于没有自己的state属性和生命周期函数,所以运行效率会比有状态组件稍微高一些

有状态组件和无状态组件之间的本质区别就是:有无state属性和有无生命周期函数

(4)组件中的props和state/data之间的区别:

  props中的数据都是外界传递过来的

  state/data中的数据都是组件私有的(通过Ajax获取回来的数据一般都是私有数据)

  props中的数据都是只读的,不能重新赋值;state/data中的数据都是可读可写的

 

posted @ 2019-12-11 12:42  浮华夕颜  Views(237)  Comments(0Edit  收藏  举报