【React】知识点归纳:组件的组合、收集表单数据

版权声明:Dream_Lees Blog https://blog.csdn.net/qq_41846861/article/details/86591730

1、组件的组合

案例效果

  • 功能: 组件化实现此功能
  1. 显示所有 todo 列表
  2. 输入文本, 点击按钮显示到列表的首位, 并清除输入的文本

功能界面的组件化编码流程(无比重要)

  1. 拆分组件: 拆分界面,抽取组件
  2. 实现静态组件: 使用组件实现静态页面效果
  3. 实现动态组件
    a. 动态显示初始化数据
    b. 交互功能(从绑定事件监听开始)

源代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>05_components_composing</title>
</head>
<body>

  <div id="example"></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/prop-types.js"></script>
  <script type="text/javascript" src="../js/babel.min.js"></script>
  <script type="text/babel">
  
    class App extends React.Component{
      constructor(props){
        super(props)
        this.state = {
          todos:['喜欢','吃饭','打代码']
        }
        this.addTodo = this.addTodo.bind(this)
      }
      addTodo (todo){
      const {todos}=this.state
        todos.unshift(todo)
        this.setState({todos})
      }
      render(){
          const {todos} = this.state
            return(
                <div>
                  <h1>Simple TODO List</h1>
                  <Add count={todos.length} addTodo={this.addTodo}/>
                  <List todos={todos} />
                </div>
            )
          }
      }
      
    class Add extends React.Component{
      constructor(props){
        super(props)

        this.handleAdd=this.handleAdd.bind(this)
      }
      handleAdd() {
        //1.读取输入数据
        const todo = this.todoInput.value.trim()
        //2.检查合法性
        if (!todo) {
          return
        }
        //3.添加
        this.props.addTodo(todo)
        //清楚输框的内容
        this.todoInput.value = ''
      }
      render(){
        return(
                <div>
                  <input type="text" ref={input => this.todoInput=input}/>
                  <button onClick={this.handleAdd}>add #{this.props.count+1}</button>
                </div>
        )
      }
    }
    Add.propTypes ={
      count:PropTypes.number.isRequired,
      addTodo:PropTypes.func.isRequired
    }
    
    class List extends React.Component{
      render(){
        const {todos} = this.props
        return(
                <ul>
                  {
                          this.props.todos.map((todo,index) =>
                                  <li key={index}>{todo}</li>)
                  }
                </ul>
        )
      }
    }
    List.propTypes ={
      todos:PropTypes.array.isRequired
    }
    //渲染组件标签 只渲染父组件
    ReactDOM.render(<App />,document.getElementById('example'))
  </script>
</body>
</html>

运行效果

在这里插入图片描述

编写代码时思考的问题

  • 问题1:数据应保存在哪个组件内?十分重要
    • 看是某个组件需要还是某些,若某个则给单个组件 若是某些组件都需要则给共同的
      父组件。此案例放在APP里,因为两个子组件都需要用到该数据。
  • 问题2:需要在子组件改变父组件的状态 (子组件不能直接改变父组件状态)
    • 状态在哪个组件,更新状态的行为就应定义在哪个组件。
    • 解决方案:父组件定义函数,传递给子组件,子组件调用
      组件化编写功能的流程
  • 注意:要理清逻辑编写代码。在父子组件中存入Add 和List子组件都需要用的输入的数据。
    • App父组件定义addTodo函数,传递给Add子组件<Add count={todos.length} addTodo={this.addTodo}/>,以便于之后子组件调用。List组件同理。
    • Add子组件通过<input type="text" ref={input => this.todoInput=input}/>(非受控组件接受数据)
      并且通过<button onClick={this.handleAdd}>add #{this.props.count+1}</button>事件处理,来调用handleAdd函数,进而调用父组件的addTodo函数。
    • List子组件内通过 this.props.todos.map((todo,index) => <li key={index}>{todo}</li>)生成一个新的数组,来返回列表。

2、收集表单数据

案例效果

  • 需求: 自定义包含表单的组件
  1. 输入用户名密码后, 点击登陆提示输入信息
  2. 不提交表单

理解

  1. 问题: 在 react 应用中, 如何收集表单输入数据
  2. 包含表单的组件分类
    a. 受控组件: 表单项输入数据能自动收集成状态
    b. 非受控组件: 需要时才手动读取表单输入框中的数据

源代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>09_form</title>
</head>
<body>
<div id="example"></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/babel">
  /*
  需求: 自定义包含表单的组件
    1. 界面如下所示
    2. 输入用户名密码后, 点击登陆提示输入信息
    3. 不提交表单
  */
  class LoginForm extends React.Component{
    constructor(props){
      super(props)
      this.state = {
        pwd:''
      }
      this.handleSubmit = this.handleSubmit.bind(this)
      this.handleChange = this.handleChange.bind(this)
    }
    handleSubmit(event){

      //1.不让表单提交,阻止默认行为(由于表单有默认的提交功能)
      event.preventDefault()
      //2.将数据读出
      const name = this.nameInput.value
      const {pwd} = this.state
	  //const password = this.pwInput.value
      //3.弹出数据
	  //alert('输入的用户名为${name},密码为${pwd}')
      alert("用户名:"+name+"\n密码:"+ pwd)
    }
    handleChange(event){
      //读取输入数据
      const pwd = event.target.value
      //更新pwd状态
      this.setState({pwd})
    }
    render(){
      return(
        <form action="/text" onSubmit={this.handleSubmit}>
          用户名:<input type="text" ref={input => this.nameInput = input}/>&nbsp;&nbsp;&nbsp;&nbsp;
          密码:<input type="password" value={this.state.pwd} onChange={this.handleChange}/>&nbsp;&nbsp;
          <input type="submit" value="登陆"/>
        </form>
      )
    }
  }
ReactDOM.render(<LoginForm/>,document.getElementById('example'))
</script>
</body>
</html>

运行效果

在这里插入图片描述
在这里插入图片描述

编写代码时思考问题

  • 1.不让表单提交,阻止默认行为(由于表单有默认的提交功能)
    event.preventDefault()
  • 此案例,读取用户名和密码时,用户名用的是非受控组件密码用的是受控组件
    • 用户名:<input type="text" ref={input => this.nameInput =input}/>&nbsp;&nbsp;&nbsp;&nbsp;
      密码:<input type="password" value={this.state.pwd} onChange{this.handleChange}/>&nbsp;&nbsp;

猜你喜欢

转载自blog.csdn.net/qq_41846861/article/details/86591730