【React事件+表单的使用+函数组件】

一、React的事件

1、react使用的是合成事件而非原生的DOM事件。在React中给元素添加事件类似于行间事件

(1)行间事件: 事件名称(‘onclick等’)纯小写,事件接收的是字符串

<button onclick='事件处理函数名'>提交</button>

(2)React类似于行间事件:事件名称采用驼峰命名法,可以通过JSX插值表达式放入函数
<button onClick={this.clickHandler}>点击</button>

2、在React中添加事件时要注意的问题

(1)事件处理函数是没有绑定this:即在事件处理函数中this为undefined

(2)若在事件处理函数中要使用this,可以将该事件处理函数变成箭头函数,或者通过bind绑定this

(3)获取事件源:

clickHandler=(e)=>{
		console.log(e.target)  //输出事件源
}

(4)在React中阻止默认事件不能用return false,必须使用event.preventDefault()

e.preventDefault()

二、表单的使用

1、将组件的状态(state)与表单的状态进行绑定:当组件的state发生改变时,修改表单的状态,或者表单的状态被改变时通过setState修改组件的状态,这样就形成了组件对表单控件的控制—受控组件

(1)输入类型的表单控件:控制value的值

💥举例:

FormComponent.jsx代码段:

import React,{Component} from "react";

class FormComponent extends Component{
    constructor(props) {
        super(props);
        this.state = {
            val:'西安'
        }
    }
    render() {
        let {val} = this.state
        return (
            <>
                <input value={val} type='text' onChange={(e =>{
                    this.setState({
                        val:e.target.value  //将表单控件的值赋给组件的状态属性
                    })
                })} />
                <br/><br/>
                <p>{val}</p>
            </>
        )
    }
}
export default FormComponent;

在这里插入图片描述

(2)单选框和复选框控制的是checked属性

受控组件:实现组件的状态和表单控件状态的同步(间接实现了双向绑定)

非受控组件:组件的状态和表单控件状态不同步(只是表单控件的初值和组件的state一致)。无需添加onChange事件, 对于输入型表单控件使用defaultValue,对于复选框和单选框使用defaultChecked

非受控组件

💥举例:

Student.jsx代码段:

import React from "react";

class Student extends  React.Component{
    state = {
        val:'兵马俑',
        checked:false
    }

    render() {
        let { val,checked } = this.state
        return(
            <>
                <input type={'text'} defaultValue={val}/>
                <br/><br/>
                <input type={'checkbox'} defaultChecked={checked}/>游泳
                <br/><br/>
                <p>{val}</p>
            </>
        )
    }
}
export default Student;

在这里插入图片描述

三、函数组件

函数组件:一个函数就是一个组件(简易组件)。函数的第一个参数是父级组件传过来的props,返回值是该组件要输出的视图

1、在React16.7之前函数组件中不能定义state,也没有生命周期。一般只作为纯粹的展示组件来使用。又称为无状态组件。

2、类组件的缺点:

  • (1)关于this的绑定问题
  • (2)很多业务逻辑写在生命周期函数componentDidMount,这样使组件变得复杂并难以维护

3、React Hooks

React Hooks:React16.8版本中开始使用。本质是一个特殊的函数,提供很多个内置的Hook,来帮助开发者实现很多只能在类组件中使用的功能。

(1)useState

useState :通过该hook,开发者可以在函数组件中使用state

语法:const [state,setState] = useState(initialState)

该方法的第一个参数’initialState’:是state的初始值,该方法返回的是一个数组

该数组的第一个元素(索引为0的元素)是state的具体值

该数组的第二个元素(索引为1的元素)是一个方法,用来更新state

💥举例:

School.jsx代码段:

import React ,{useState} from "react";
function School(){
    const [schoolName,setSchoolName] = useState('西安邮电学校')

    return(
        <>
            <p>学校名称:{schoolName}</p>
            <button onClick={()=>{
                setSchoolName('西安邮电大学')
            }}>学校新名称</button>

        </>
    )
}
export default School;

在这里插入图片描述
点击按钮后:
在这里插入图片描述
注意的问题:

		    a、useState的返回setState方法是同类组件的setState,是一个异步方法,需要组件更新后
			
			     state的值才能变成新值
				 
			b、useState的返回setState方法不能像类组件中的setState方法来更改多个属性的值
			
			c、在函数组件中可以使用useState创建多个state

💥举例:

School.jsx代码段:

import React ,{useState} from "react";
function School(){
    const [schoolInfo,setSchoolInfo] = useState({name:'西电',address:'光华路'})

    return(
        <>
            <p>学校名称:{schoolInfo.name}</p>
            <p>学校地址:{schoolInfo.address}</p>
         
            <button onClick={()=>{
                setSchoolInfo({
                    //...schoolInfo,
                    name:'西安电子科技大学',
                    address: '草堂寺'
                    //如果只改name的值,而不写address,address的值会变为空;如果想只改name,就需要先利用...schoolInfo解构,这样改就不会影响下面的其他属性了
                })
            }}>修改对象的值</button>
        </>
    )
}
export default School;

在这里插入图片描述
点击后
在这里插入图片描述

(2)useRef

useRef:看成是createRef的Hook版。使用方法:

(1)先将ref存入变量

   let el = useref()

(2)再将变量与DOM节点进行绑定,通过Ref的current属性来获取节点

<p ref={ el }>web开发</p>
el.current

useRef的作用:

(1)可以绑定DOM组件

(2)可以获取组件渲染之前的数据

💥举例:

RefDemo.jsx代码段:

import React,{useRef} from "react";

function RefDemo(){
    let elP = useRef();

    return (
        <div>
            <p ref = { elP }>Web开发</p>
            <button onClick={()=>{
                console.log(elP.current)
            }
            }>显示内容</button>
        </div>
    )
}
export default RefDemo;

App.js中代码段:

import logo from './logo.svg';
import './App.css';
import RefDemo from "./components/RefDemo";

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
      </header>
        <RefDemo/>
    </div>
  );
}

export default App;

显示如下:
在这里插入图片描述

(3)useEffect

useEffect:在类组件中副作用通常在componentDidMountcomponentDidUpdatecomponentWillUnMount 生命周期函数中进行处理。在函数组件中useEffect相当于以上三个钩子函数的集合体

包含两个参数:第一参数是执行时的回调函数、第二个参数是依赖参数,并且回调函数还有一个返回参数
(1)依赖参数:是一个数组,数组中存放的是要依赖的依据,当这些数据更新时就会执行回调函数
(2)执行过程:
组件挂载–>执行副作用(回调函数)–>组件更新–>执行清理函数

💥举例:

Course.jsx代码段:

import React, {useState,useEffect} from "react";

function Course(){
    const [course,setCourse] = useState('Web高级工程师')
    const [num,setNum] = useState(1)

    useEffect(()=>{
        console.log('组件挂载或更新')
        return ()=>{  //返回回调函数
            console.log('清理更新之前的一些内容,或检测组件即将卸载')
        }
    },[num])

    return(
        <>
            <div>
                选择课程:
                <select
                    value={ course }
                    onChange={ ({target})=>{ setCourse(target.value)} }
                >
                    <option>Web全栈工程师</option>
                    <option>Web高级工程师</option>
                    <option>Web-UI工程师</option>
                </select>
            </div>
            <div>
                购买数量:
                <input type={'number'}
                       value={ num }
                       min={1}
                       onChange={({target})=>{ setNum(target.value)}}
                />
            </div>
        </>

    )
}

export default Course;

App.js代码段

import logo from './logo.svg';
import './App.css';
import Course from "./components/Course";

import {useState} from "react";

function App() {
    const [show,setShow] = useState(true); //由show决定Course组件是否显示
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
      </header>
        { show?<Course/>:''}    {/*若show为true则显示Course组件,否则不显示*/}

        <br/><br/>

        <button onClick={()=>{ setShow(!show)}}>{ show?'隐藏课程':'显示课程'}</button>
    </div>
  );
}

export default App;

注意:类组件需要通过render(){return()}才能返回渲染 ,而 函数组件直接通过return返回来渲染

4、Hooks的使用规则

(1)只能在函数组件和自定义的Hooks中调用Hooks。类组件和普通函数不能使用Hooks

(2)只能在函数的第一层中调用Hooks。在函数中若使用了流程控制语句(if、for、while),在流程控制语句中不能使用Hooks;若函数中定义了子函数,子函数中也不能使用Hooks。

5、自定义Hooks(示例)

自定义Hooks:在应用中可以将一些需要重复使用的逻辑自定义成Hook

示例:自定义一个Hook,返回一个和滚动条位置实时同步的state

useScrollY.jsx代码段:

import {useState,useEffect} from "react";

function useScrollY(){
    let [scrollY,setScrollY] = useState(0)
    function scroll(){

        //获取window窗口的垂直滚动条
        setScrollY(window.scrollY)
    }

    useEffect(()=>{
        window.addEventListener('scroll',scroll);  //注册监听

        return ()=>{
            window.removeEventListener('scroll',scroll) //注销监听
        }
    },[]);

    return scrollY;
}

export default useScrollY;

App.js代码段:

import logo from './logo.svg';
import './App.css';
import useScrollY from "./components/useScrollY";

function App() {

    let scrollY = useScrollY();
    
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
      </header>
        <div style={{
            border:'1px solid #000',
            height:'1500px'
        }}>
            <p style={{position:'fixed',left:0,top:0}}>当前滚动条的位置是:{scrollY}</p>
        </div>
   </div>
  );
}

export default App;

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值