Event handling, controlled and uncontrolled components, higher order functions and function currying

event handling

  1. Specify the event handler function through the onXxx attribute (note the case)
  • React uses custom (synthetic) events instead of native DOM events.
    Advantages: onClick is more compatible than onclick (native event)
  • Events in React are 事件委托handled by means (delegating to components 最外层的元素)
    Advantages: more efficient
  • The event attribute in the jsx syntax accepts a function, so there is no need to write after the function name (); if parameters must be passed, the return value of the function needs to be a function as well.
    eg:
import React, {
    
     Component } from 'react'
import PropyTypes from 'prop-types'
import './index.css'

export default class index extends Component {
    
    
  // 对Props进行类型的限制
  static propsTypes = {
    
    
    updateTodo: PropyTypes.func.isRequired,
    id: PropyTypes.string.isRequired,
    name: PropyTypes.string.isRequired,
    done: PropyTypes.bool.isRequired
  }
  state = {
    
    mouse:false}
  handleMouse = (flag)=>{
    
    
    // 在标签中函数使用了括号
    return () => {
    
    
      this.setState({
    
    mouse:flag})
    }
  }
  handleChange = (id) => {
    
    
    return (event) => {
    
    
      // 注意是checked不是value
      const checked =  event.target.checked;
      this.props.updateTodo(id, checked)
    }
  }
  handleDelete = (id)=>{
    
    
    if(window.confirm("确定删除吗?")){
    
    
      this.props.deleteTodo(id)
    }
  }
  render() {
    
    
    const {
    
    id, name, done} = this.props
    const {
    
    mouse} = this.state;
    return (
        <li style={
    
    {
    
    backgroundColor: mouse? '#ddd':'white'}} onMouseEnter = {
    
    this.handleMouse(true)} onMouseLeave = {
    
    this.handleMouse(false)}>
            <label>
              {
    
    /* 使用checked,必须要结合onChange事件才能进行修改
               而defaultChecked,初次页面展示时是否勾选,当数据再发生改变的时候就不好用了*/}
                <input type="checkbox" checked = {
    
    done} onChange = {
    
    this.handleChange(id)}/>
                <span>{
    
    name}</span>
            </label>
            <button onClick={
    
    () => {
    
    this.handleDelete(id)}} className="btn btn-danger" style={
    
    {
    
    display:mouse?"block":"none"}}>删除</button>
        </li>
    )
  }
}
  1. You can use ref to store the current node, and then combine the event callback function to process the node data.
  2. You can also event.targetobtain the DOM element object where the event occurred. When the element where the event occurs happens to be the element to be operated on, we try to use evet.target to obtain data, and do not use ref eg
    excessively:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>字符串ref</title>
</head>
<body>
    <!-- 容器 -->
    <div id="test"></div>

    <script type="text/javascript" src="../js/react.development.js"></script>
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/javascript" src="../js/prop-types.js"></script>

    <script type="text/babel">
        //  <!-- 1.创建类式组件 -->
        class Demo extends React.Component{
      
      
            // React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专川用”的(即一个createRef只能存储一个dom元素)
            myRef = React.createRef()

            showDataClick = ()=>{
      
      
                alert(this.myRef.current.value)
            }
            showDataBlur = (event)=>{
      
      
                // event发生事件的事件源
                alert(event.target.value)
            }
            render(){
      
      
                return (
                    <div>
                        {
      
      /*ref方式*/}
                        <input ref={
      
      this.myRef} type="text" id="input1" placeholder="点击按钮提示数据"/>
                        <button onClick={
      
      this.showDataClick}>点我提示左侧数据</button>&nbsp;
                        {
      
      /*event.Target方式*/}
                        <input onBlur={
      
      this.showDataBlur} type="text" placeholder="失去焦点提示数据"/>
                    </div>
                )
            }
        }

        // <!--2.渲染虚拟DOM到页面 -->
        ReactDOM.render(<Demo/>,document.getElementById('test'))  
    </script>
</body>
</html> 

Controlled and Uncontrolled Components

  • Uncontrolled components: All 输入类the DOM in the form 现用现取are uncontrolled components
    现用现取, that is, they can be obtained when the data is needed
  • Controlled component: store data in state first, and then display it on the page. ——It’s a bit similar to vue’s two-way data binding, but it needs to be implemented manually in react.

Requirement:
insert image description here
There is a user name and password. When you click to log in, a window will pop up to prompt the user name and password.

Controlled component implementation: - data is stored in state

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>受控组件</title>
</head>
<body>
    <!-- 容器 -->
    <div id="test"></div>

    <script type="text/javascript" src="../js/react.development.js"></script>
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/javascript" src="../js/prop-types.js"></script>

    <script type="text/babel">
        //  <!-- 1.创建类式组件 -->
        class Login extends React.Component{
      
      
            // 初始化状态
            state={
      
      
                username:'',
                password:''
            }
            handlesubmit = (event)=>{
      
      
                event.preventDefault()//阻止默认事件,表单的提交
                const {
      
      username,password} = this.state
                alert(`用户名:${ 
        username},密码:${ 
        password}`)
            }
            // 保存用户名到username
            saveUsername = (event)=>{
      
      
                this.setState({
      
      username:event.target.value})
            }
            // 保存
            savePassword = (event)=>{
      
      
                this.setState({
      
      password:event.target.value})
            }
            render(){
      
      
                return(
                    <form action="http://www.baidu.com" onSubmit={
      
      this.handlesubmit} >
                        {
      
      /*onchange也是一个原生的事件,当内容发生改变就会调用该函数*/}
                        用户名:<input onChange={
      
      this.saveUsername} type="text" name="username"/><br/>
                        密码:<input onChange={
      
      this.savePassword} type="password" name="password"/><br/> 
                        <button>登录</button>
                    </form>
                )
            }
        }
        // <!--2.渲染虚拟DOM到页面 -->
        ReactDOM.render(<Login/>,document.getElementById('test'))
        
    </script>
    <!-- 受控组件:数据先存放在state中,再显示到页面上 -->

</body>
</html> 

Uncontrolled component implementation: - data is stored on the component instance

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>非受控组件</title>
</head>
<body>
    <!-- 容器 -->
    <div id="test"></div>

    <script type="text/javascript" src="../js/react.development.js"></script>
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/javascript" src="../js/prop-types.js"></script>

    <script type="text/babel">
        //  <!-- 1.创建类式组件 -->
        class Login extends React.Component{
      
      
            handlesubmit = (event)=>{
      
      
                event.preventDefault()//阻止默认事件,表单的提交
                const {
      
      username,password} = this
                alert(`用户名:${ 
        username.value},密码:${ 
        password.value}`)
            }
            render(){
      
      
                return(
                    // form表单默认是get请求,query参数
                    // form会默认提交并刷新页面,即使没有配路径
                    <form action="http://www.baidu.com" onSubmit={
      
      this.handlesubmit} >
                        用户名:<input ref={
      
      c=>this.username=c} type="text" name="username"/><br/>
                        密码:<input ref={
      
      c=>this.password=c} type="password" name="password"/><br/> 
                        <button>登录</button>
                    </form>
                )
            }
        }
        // <!--2.渲染虚拟DOM到页面 -->
        ReactDOM.render(<Login/>,document.getElementById('test'))
        
    </script>
    <!-- 非受控组件:表单中所有输入类的DOM 现用现取的就是非受控组件 -->

</body>
</html> 

Higher order functions and function currying

higher order functions

The above code is a bit redundant, the function structure is similar but the value is different, it can be extracted as a function.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>字符串ref</title>
</head>
<body>
    <!-- 容器 -->
    <div id="test"></div>

    <script type="text/javascript" src="../js/react.development.js"></script>
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <script type="text/javascript" src="../js/babel.min.js"></script>
    <script type="text/javascript" src="../js/prop-types.js"></script>

    <script type="text/babel">
        //  <!-- 1.创建类式组件 -->
        class Login extends React.Component{
      
      
            // 初始化状态
            state={
      
      
                username:'',
                password:''
            }
            handlesubmit = (event)=>{
      
      
                event.preventDefault()//阻止默认事件,表单的提交
                const {
      
      username,password} = this
                alert(`用户名:${ 
        this.state.username},密码:${ 
        this.state.password}`)
            }
            saveFormData=(dataType)=>{
      
      
                // onChange的值需要是一个回调函数,onChange回调函数的参数是event
                return (event)=>{
      
      
                    // dataType是一个变量,作为键值时需要使用[],确保读取变量中的值
                     this.setState({
      
      [dataType]: event.target.value})
                }
            }
            render(){
      
      
                return(
                    <form action="http://www.baidu.com" onSubmit={
      
      this.handlesubmit} >
                        用户名:<input onChange={
      
      this.saveFormData('username')} type="text" name="username"/><br/>
                        密码:<input onChange={
      
      this.saveFormData('password')} type="password" name="password"/><br/> 
                        <button>登录</button>
                    </form>
                )
            }
        }
        // <!--2.渲染虚拟DOM到页面 -->
        ReactDOM.render(<Login/>,document.getElementById('test'))
    </script>
</body>
</html> 

The above code saveFormDatais a higher-order function.

Higher-order function: If a function meets any of the following two specifications, then the function is a higher-order function.

  • If the A function receives a parameter that is a function, then A can be called a higher-order function.
  • If the return value of function A is still a function, then A can be called a higher-order function.

Common high-order functions include: Promise, setTimeout, arr.map(), etc.

function currying

Currying of functions: Through function calls 继续返回函数, the function encoding form that receives parameters multiple times and finally processes them in a unified manner is realized.
The above code applies currying:

    saveFormData=(dataType)=>{
    
    
        return (event)=>{
    
    
             this.setState({
    
    [dataType]: event.target.value})
        }
    }

Guess you like

Origin blog.csdn.net/mantou_riji/article/details/127270512