React入门(二)


上期 戳这里~

一.无状态组件

​ 顾名思义就是组件内部没有(不需要)state,无状态组件也可以理解为展示组件,仅做展示用,可以根据外部传来的props来渲染模板的内容,内部没有数据。

  //无状态组件:组件内部没有state,可以使用函数式组件。它只负责展示
    let Book = (props) => (
      <div>
        <p>书名:{props.name}</p>
        <p>作者:{props.author}</p>
      </div>
    );

仅仅只是一个函数,就ok了。

二.有状态组件

​ 有状态组件就是不但外部可以传入,内部也有state。

​ 有状态组件也可以理解为容器组件,用来容纳展示组件,在容器组件里处理数据的逻辑,把结果在展示组件里呈现。

​ 创建有状态组件如下:

 // 有状态组件:有state,负责数据的处理。
    class Books extends React.Component {//容器组件
      constructor(props) {
        super();
        this.state = {
          bookList: [
            {
              name: "三国",
              author: "罗贯中",
            },
            {
              name: "哆啦A梦",
              author: "哈哈哈",
            },
            {
              name: "皮卡丘",
              author: "xixi",
            },
          ],
        };
      }
      render() {
        return(
          <div>
            <h1>书籍列表</h1>
            <ul>
               {/*Book为展示组件*/}
              {this.state.bookList.map((item,index) => (
                <Book name={item.name} author={item.author} key={index}/> 
              ))}
            </ul>
          </div>
        );
      }
    }
    ReactDOM.render(
      <div>
        <Books />
      </div>,
      document.getElementById("box")
    );

在这里插入图片描述

注意

做项目时,经常会把有状态组件和无状态组件进行结合使用。

1)、 有状态组件:一般会使用类组件,处理数据的业务逻辑,包括和后端进行交互,获取数据。把数据传给无状态组件

2)、 无状态组件:一般会使用函数式组件,只做展示用,没有自己的数据,会接收有状态组件传来的数据。

三. 事件处理

3.1事件特点:

1、React 事件绑定属性的命名采用驼峰式写法,而不是小写。如:onClick。

2、如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM 元素的写法)

3、在 React 中另一个不同的是,不能使用return false 的方式阻止默认行为, 你必须使用 preventDefault。

4、事件处理函数里的this是undefined(啊………),如果希望事件处理函数里的this是React组件对象本身,则需要用bind。

3.2 事件语法

3.2.1格式

<JSX元素 onClick={this.实例方法|函数体} />

示例:

  class Books extends React.Component {
      constructor(props) {
        super();
      }
      fn(){
        console.log("点击了~");
      }
      render() {
        return(
          <div>
           <input type="button" value="测试" onClick={this.fn}/>
          </div>
        );
      }
    }
    ReactDOM.render(
      <div>
        <Books />
      </div>,
      document.getElementById("box")
    );

重点来袭~
在这里插入图片描述

3.2.2事件处理函数里的this

事件处理函数里的this是undefined,如何让事件处理函数里的this是React组件对象本身
在这里插入图片描述

  • 使用bind
    1)、构造器(构造函数)里:this.方法=this.方法.bind(this)
    2)、在事件绑定时写,onClick={this.方法.bind(this)}
 class Books extends React.Component {
      constructor(props) {
        super();
        // 1、使用bind,让事件处理函数了的this是react组件对象。bind不会调用函数,会绑定该函数,返回一个新的函数。
        // this.fn02 = this.fn01.bind(this);
        this.fn01=this.fn01.bind(this);
      }
      fn01(){
        console.log("点击了~");
        console.log("this",this);
      }
      render() {
        return(
          <div>
           <input type="button" value="测试01" onClick={this.fn01}/>
           {/*直接使用bind*/}
           <input type="button" value="测试02" onClick={this.fn01.bind(this)}/>
          </div>
        );
      }
    }
    ReactDOM.render(
      <div>
        <Books />
      </div>,
      document.getElementById("box")
    );

在这里插入图片描述

  • 使用箭头函数
    1)、事件绑定时,使用箭头函数:onClick={()=>this.方法()}
  class Books extends React.Component {
      constructor(props) {
        super();
       fn01(){
         console.log("点击了~");
        console.log("this",this);
       }
      render() {
        return (
          <div>   
           <input type="button" value="测试03" onClick={()=>this.fn01()}/>
          </div>
        );
      }
    }
    ReactDOM.render(
      <div>
        <Books />
      </div>,
      document.getElementById("box")
    );

2)、定义方法时,直接使用箭头函数: 方法=()=>{箭头函数定义方法}

  class Books extends React.Component {
      constructor(props) {
        super();
      // 4、定义方法时,使用箭头函数
      fn04 = () => {
        console.log("点击了~");
        console.log("this", this);
      };
      render() {
        return (
          <div>
            <input type="button" value="测试04" onClick={this.fn04} />
          </div>
        );
      }
    }
    ReactDOM.render(
      <div>
        <Books />
      </div>,
      document.getElementById("box")
    );

在这里插入图片描述

3.2.3事件对象

event对象是经过react处理过的。

如何获取事件对象------直接声明即可。

实例方法(ev) ev 代理事件对象 ,ev.target 返回虚拟Vdom

事件对象的获取:

1)、直接声明(没有其它参数的情况下)

 //无其他参数
      fn01 = (ev) => {
        console.log("ev", ev);
        //    真实DOM
        console.log("ev.target", ev.target);
      };

 <input type="button" value="测试01" onClick={this.fn01} />

2)、箭头函数里直接声明(有其它参数的情况下)

 //    有其他参数
       // 注意:这已经不是事件处理函数了
      fn02 = (ev, str) => {
        console.log("ev", ev);
        console.log("ev.target", ev.target);
        console.log("str", str);
        console.log("this", this);
      };
//注意:给onClick绑定的函数,还是只有一个参数,这个参数就是事件对象,此处在绑定的函数里再调用另外一个函数进行传参
<input
              type="button"
              value="测试02"
              onClick={(ev) => this.fn02(ev, "hi")}
            />

注意:给事件属性绑定的函数,永远只会有一个参数,该参数就是事件对象。
在这里插入图片描述

3.2.4阻止浏览器的默认行为:

在这里插入图片描述
​ 只能用preventDefault,不能在事件函数里使用return false。
原封不懂得输入到大脑就好啦~简单!

四.组件的内容 :children

组件的内容,使用 children属性获取

 class Books extends React.Component {
      constructor(props) {
        super();
      }

      render() {
        return (
          <div>
            <p>我是上面的片</p>
            {this.props.children}
            <p>我是下面的片</p>
          </div>
        );
      }
    }
    ReactDOM.render(
      <div>
        <Books>
          <h1>我是组件之间的内容</h1>
        </Books>
      </div>,
      document.getElementById("box")
    );

在这里插入图片描述

五.refs

5.1获取DOM

表示对组件真正实例(也就是html标签,也就是DOM对象)的引用,其实就是ReactDOM.render()返回的组件实例;ref可以写在html标签里,也可以写在组件(自定义标签里),和vue的ref是同样的意思。

​ 官方建议: 勿过度使用 Refs(尽量不要操作DOM),在对逻辑进行处理的时候尽量优先考虑state(数据驱动)

5.2用法

1). 赋值为 字符串(官方不推荐使用)

  class Books extends React.Component {
      constructor(props) {
        super();
      }
      fn01 = () => {
        this.refs.username.value = "hhh";
      };
      render() {
        return (
          <div>
             {/*赋值为字符串*/}
            <input type="text"  ref="username" />
            <input type="button" value="测试01" onClick={this.fn01} /><br/>
          </div>
        );
      }
    }
    ReactDOM.render(
      <div>
        <Books></Books>
      </div>,
      document.getElementById("box")
    );

2). 赋值为 回调函数

​ 当给 HTML 元素添加 ref 属性时,ref 回调接收了底层的 DOM 元素作为参数。

​ ref 回调会在componentDidMount 或 componentDidUpdate 这些生命周期回调之前执行。

//ref的值赋成回调函数时,回调的参数就是当前dom元素。
// callback refs 回调
<jsx ref={el => this.定义一个实例属性 = el} //el就是dom对象
this.定义一个实例属性 //后期用作访问jsx元素
//当组件挂载时,将 DOM el元素传递给 ref 的回调
//当组件卸载时,则会传递 null。
//ref 回调会在 componentDidMount 和 componentDidUpdate 生命周期之前调用
如:
<input type=“text” ref={(currDom) => this.input1 = currDom} />
<input type=“text” ref={(currDom) => this.input2 = currDom} />

 class Books extends React.Component {
      constructor(props) {
        super();
        this.ipt=null;
      }
      fn02=()=>{
        this.ipt.value = "啦啦啦";
    }
      render() {
        return (
          <div>
            <input type="text" ref={el=>this.ipt=el}/>
            <input type="button" value="测试02" onClick={this.fn02}/>
          </div>
        );
      }
    }
    ReactDOM.render(
      <div>
        <Books></Books>
      </div>,
      document.getElementById("box")
    );

3). React.createRef() (React16.3提供)

​ 使用此方法来创建ref。将其赋值给一个变量,通过ref挂载在dom节点或组件上,该ref的current属性将能拿到dom节点或组件的实例。

//1、在构造函数里
// 实例化
this.firstRef = React.createRef() //发生在构造器
//2、挂载在ref属性上
//3、获取dom原始
this.firstRef.current //current是官方的属性

 class Books extends React.Component {
      constructor(props) {
        super();
        this.firstRef = React.createRef(); //发生在构造器
      }
      fn03=()=>{
        console.log(this.firstRef.current);
    }
      render() {
        return (
          <div>
            {/*  React.createRef() (React16.3提供) */}
            <input type="text" ref={this.firstRef} />
            <input type="button" value="测试03" onClick={this.fn03} />
          </div>
        );
      }
    }
    ReactDOM.render(
      <div>
        <Books></Books>
      </div>,
      document.getElementById("box")
    );

在这里插入图片描述

请添加图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值