React入门04-表单受控绑定、获取DOM、组件通信、案例分析

表单的受控绑定

        表单的受控绑定在我看来其实就是数据的双向绑定,我们定义的状态变量值可以影响input输入框的内容,同时input输入框的内容改变也会同时存储到状态变量当中,实现的关键点有两个。

  • 创建状态变量,将变量绑定到input框的value属性上,实现从变量到input框的数据绑定
  • 利用onChange事件,通过event.target.value将数据更新到状态变量上,实现从input框到变量的数据流动,最终两个步骤实现了数据的双向绑定。
    import { useState } from 'react';
    
    function App() {
    
      const [text, setText] = useState('')
    
      const handleChange = (e) => {
        setText(e.target.value)
      }
    
      return (
        <div>
          <input type='text' value={text} onChange={handleChange}></input>
          <p>{text}</p>
        </div>
      );
    }
    
    export default App;

        如图所示,当我们改变输入框内容时,下面的文字内容也会跟着一起改变。

 

获取DOM元素 

        在一些场景当中我们也需要获取并操作DOM元素,在这里React提供了useRef的钩子函数,获取DOM元素的一般流程如下:

  1. 使用useRef(null)定义变量
  2. 将变量绑定到所需要的获取的元素的ref属性上
  3. 使用变量上的.current就会指向该DOM元素(注意:需要在DOM加载完毕时才能够获取到,
    // 获取并打印DOM元素
    import { useRef } from 'react';
    
    function App() {
    
      const htmlElement = useRef(null)
    
      const getDomElement = () => {
        console.log(htmlElement.current)
      }
    
      return (
        <div>
          <span ref={htmlElement}>this is the element we need</span>
          <button onClick={getDomElement}>Get span</button>
        </div>
      );
    }
    
    export default App;

        点击按钮后确实获取到了我们所需要的span标签。

 

案例分析

        在本篇文章将会分析列表渲染,删除功能,tab的切换功能以及列表的排序,通过输入框插给列表插入新的信息。

列表渲染与删除单项

        列表渲染已经在前期的入门教程中介绍过了,该部分的重点将会聚焦于删除列表元素并让视图重新渲染。

        下面所示是列表渲染的基础代码(不要忘记绑定key~~),我们构建了一个简单的列表,包含id、姓名和每个人的年龄。


import { useState } from 'react';

function App() {
  // 列表包含id、name、age属性
  const users = [
    { id: 1, name: 'Alice', age: 20 },
    { id: 2, name: 'Bob', age: 21 },
    { id: 3, name: 'Charlie', age: 22 }
  ]

  // 创建状态变量
  const [list, setList] = useState(users)

  return (
    <div className="App">
      {/* 列表渲染list */}
      <ul>
        {list.map((user) => (
          <li key={user.id}>{user.name} - {user.age}</li>
        ))}
        </ul>
    </div>
  );
}

export default App;

        实现效果如下图所示。

        接下来实现删除按钮,在<li>元素内新增一个button元素,设置点击事件,传递的参数是该元素的id,删除函数内部实现使用filter函数,返回匹配的元素组成的新的数组,调用setList函数更新list值的同时触发渲染浏览器视图。

        新增button按钮。

 return (
    <div className="App">
      {/* 列表渲染list */}
      <ul>
        {list.map((user) => (
          <li key={user.id}>{user.name} - {user.age}<button onClick={()=>handleDel(user.id)}>Delete</button></li>
        ))}
        </ul>
    </div>

         处理点击事件的函数。

  const handleDel = (id) => {
    setList(list.filter((user) => user.id !== id))
  }
Tab切换列表排序 

        接着沿用刚刚定义的列表,首先将排序打乱,我们的Tab分别可以按照年龄排序或者按照id排序,在该部分我们实现的思路是:

        第一,通过列表渲染出Tab,每个Tab包含一个type信息,再绑定点击事件的时候我们将type信息传递进入处理点击事件的函数,们需要一个状态变量来存储type信息,在触发点击事件的时候,type的值改变的同时通过使用三元运算符(或者与运算符)控制className实现类名的动态添加,从而实现Tab的样式切换。 

        第二,type传入处理函数的时候,根据if条件语句排序list,调用setList,触发页面的重新渲染。 

import { useState } from 'react';
import './index.css'

function App() {
  // 列表包含id、name、age属性
  const users = [
    { id: 3, name: 'Alice', age: 50 },
    { id: 2, name: 'Bob', age: 44 },
    { id: 5, name: 'Charlie', age: 18 }
  ]

  // 创建状态变量
  const [list, setList] = useState(users)

  // 定义删除函数
  const handleDel = (id) => {
    setList(list.filter((user) => user.id !== id))
  }

  // 定义tablist
  const tabList = [
    { type:'id', content:'根据ID排序'},
    { type:'age', content:'根据年龄排序'}
  ]

  const [type, setType] = useState('id')

  const handleTabChange = (type) => {
    setType(type)
    setList([...list].sort((a, b) => {
      return type === 'id' ? a.id - b.id : a.age - b.age
    }))
  }

  return (
    <div className="App">
      {
        tabList.map((tab) => (
          <span key={tab.type} onClick={()=>handleTabChange(tab.type)} className={`tab ${type === tab.type ? 'active' : ''}`}>{tab.content}</span>
        ))
      }
      {/* 列表渲染list */}
      <ul>
        {list.map((user) => (
          <li key={user.id}>{user.name} - {user.age}<button onClick={()=>handleDel(user.id)}>Delete</button></li>
        ))}
        </ul>
    </div>
  );
}

export default App;

         补充:在index.css定义了基础的样式,如下所示。

  .tab {
    display: inline-block;
    margin-right: 10px;
    cursor: pointer;
  }

  .active {
    color: red;
  }
新增列表元素

        新增列表元素使用到了我们上面刚刚学过的Input数据双向绑定以及获取DOM元素。获取DOM元素主要用于再次在输入框获得焦点。

        首先让我们来看看如何通过表单受控绑定实现新增列表元素(代码只展示新增内容)。

 const[textVal, setTextVal] = useState('')

  const handleInput = (e) => {
    setTextVal(e.target.value)
  }

  const handelAddListItem = () =>{
    setList([...list, {id: list.length + 1, name: textVal, age: 20}])
    setTextVal('')
  }

        在JSX中新增下面的代码内容,主要就是应用表单受控绑定。

<input type='text' value={textVal} onChange={handleInput}></input>
<button onClick={handelAddListItem}>Add</button>

        这两以来我们就能随意增加内容啦!!!

        然后我们需要在点击Add按钮后依然让焦点在输入框内,主要需要两点:

  • 获取DOM元素
  • 调用.focus方法 

        新增的代码如下所示,主要就是定义inputRef和input元素绑定ref属性用于获取DOM元素,textVal.current.focus()用于聚焦。

const inputRef = useRef(null)

const handelAddListItem = () =>{
    setList([...list, {id: list.length + 1, name: textVal, age: 20}])
    setTextVal('')
    textVal.current.focus()
  }

<input type='text' value={textVal} onChange={handleInput} ref={inputRef}></input>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值