React---组件基础

一、React 组件介绍

  • 使用 React 就是在用组件
  • 组件表示页面中的部分功能
  • 组合多个组件实现完整的页面功能
  • 特点:可复用、独立、可组合

二、 React 组件的两种创建方式

1、使用函数创建组件

        函数组件:使用 JS 的函数(或箭头函数)创建的组件
如下所示即为一个组件:

function Hello(){
	return (
		<div>这是一个函数组件</div>
	)
}
  • 约定1:函数名称必须以大写字母开头
  • 约定2:函数组件必须有返回值,表示该组件的结构
  • 如果返回值为 null,表示不渲染任何内容

渲染函数组件:用函数名作为组件标签名
如下:

let root = document.getElementById('root')
ReactDom.render(< Hello />,root)

打印结果为:
在这里插入图片描述

注意:组件标签可以是单标签也可以是双标签

2、 使用类创建组件

       类组件:使用 ES6 的 class 创建的组件
如下所示:

class Hello extends React.Component{
	render(){
		return (
			<div>这是一个类组件</div>
		)
	let root = document.getElementById('root')
	ReactDOM.render(<Hello />,root)

打印结果为:
在这里插入图片描述

  • 约定1:类名称也必须以大写字母开头
  • 约定2:类组件应该继承 React.Component 父类,从而可以使用父类中提供的方法或属性
  • 约定3:类组件必须提供 render() 方法
  • 约定4:render() 方法必须有返回值,表示该组件的结构

三、React 事件处理

1、事件绑定

         React 事件绑定语法与 DOM 事件语法相似
语法:on+事件名称={事件处理程序}
比如:

onClick={() => {}}

注意:React 事件采用驼峰命名法,比如:onMouseEnteronFocus

1、在函数组件中绑定事件

如下所示:

<body>
    <div id="root"></div>
    <script type="text/babel">
        let root = document.getElementById('root')
        function App(){
            function handleClick(){
                console.log('单击触发了函数事件处理')
            }
            return (
                <button onClick={handleClick}>单击</button>
            )
        }
        //元素渲染
        ReactDOM.render(<App />,root)
    </script>
</body>

打印结果为:
在这里插入图片描述

2、在类组件中绑定事件

如下所示:

<body>
    <div id="root"></div>
    <script type="text/babel">
        let root = document.getElementById('root')
        class App extends React.Component{
            handClick(){
                console.log('单击触发了类事件处理')
            }
            render(){
                return (
                    <button onClick={this.handClick}>点击</button>
                )
            }
        }
        //元素渲染
        ReactDOM.render(<App />,root)
    </script>
</body>

打印结果为:
在这里插入图片描述

2、事件对象

       可以通过事件处理程序的参数获取到事件对象,React 中的事件对象叫做:合成事件(对象)。
       合成事件:兼容所有浏览器,无需担心跨浏览器兼容性问题
       例如:我们想要通过一个a标签,不发生事件的跳转,而实现其点击事件。示例如下:

<body>
    <div id="root"></div>
    <script type="text/babel">
        let root = document.getElementById('root')
        class App extends React.Component{
           handleClick(e){
               e.preventDefault()
               console.log('a标签的单击事件触发了')
               }
               render(){
                   return (
                       <a href="https://blog.csdn.net/m0_48375854?type=blog" onClick={this.handleClick>bear*6</a>
                   )
           }
        }
        //元素渲染
        ReactDOM.render(<App />,root)
    </script>
</body>

结果为:
在这里插入图片描述

四、有状态组件和无状态组件

函数组件又叫做无状态组件,类组件又叫做有状态组件。

  • 状态(state)即数据
  • 函数组件没有自己的状态,只负责数据展示
  • 类组件有自己的状态,负责更新 UI,让页面“动” 起来

         比如计数器案例中,点击按钮让数值加 1 。0 和 1 就是不同时刻的状态,而由 0 变为 1 就表示状态发生了变化。状态变化后,UI 也要相应的更新。React 中想要实现该功能,就要使用有状态组件来完成。

五、组件中的 state 和 setState()

1、 state的基本使用状态即数据

  • 状态是私有的,只能在组件内部使用
  • 通过 this.state 来获取状态

如下例所示,初始化count的值为0:

<body>
    <div id="root"></div>
    <script type="text/babel">
        let root = document.getElementById('root')
       class App extends React.Component{
         //法一:
        //    constructor(){
        //        super()
        //        //初始化state
        //        this.state = {
        //            count:0
        //        }
        //    }
        //法二:
        state = { 
            count:0
        }
           render(){
               return (
                   <h1>计数器:{this.state.count}</h1>
               )
           }
       }
        //元素渲染
        ReactDOM.render(<App />,root)
    </script>
</body>

最终输出的结果为:
在这里插入图片描述

2、 setState()修改状态

         我们想要将计数器的值从0变化到1,这个时候,我们就需要让状态发生变化,该如何修改值呢?
         语法:this.setState({ 要修改的数据 })
         setState() 作用:修改 state 和更新UI
代码如下:

<body>
    <div id="root"></div>
    <script type="text/babel">
        let root = document.getElementById('root')
       class App extends React.Component{
           state = {
               count:0
           }
           render(){
               return (
                  <div>
                    <h1>计数器:{this.state.count}</h1>
                   <button onClick={()=>{
                       this.setState({
                           count:this.state.count+1
                       })
                   }}>点击+1</button>
                    </div>
               )
           }
       }
        //元素渲染
        ReactDOM.render(<App />,root)
    </script>
</body>

实现效果为:

在这里插入图片描述
注意:不能直接修改 state 中的值
如果不用箭头函数写呢?如下所示:

class App extends React.Component{
        state={
             count:0
        }
        add(){
             this.setState({
                  count:this.state.count+1
              })}
         render(){
              return (
                 <div>
                      <div>修改状态的值为:{this.state.count}</div>
                      <button onClick={this.add}>+1</button>
                 </div>
              )
          }
        }

打印的结果为:
在这里插入图片描述
         可知:发生错误,这是因为事件处理程序中的this指向是undefine,而箭头函数没有this指向的问题。

六、事件绑定 this 指向

要处理事件绑定中的this指向问题,有三种方法。

1、箭头函数

         利用箭头函数自身不绑定this的特点,以 render() 方法中的 this 为组件实例,可以获取到 setState(),如下所示:

<body>
    <div id="root"></div>
    <script type="text/babel">
        let root = document.getElementById('root')
       class Hello extends React.Component{
           state = {
               count:0
           }
           add(){
               this.setState({count:this.state.count+1})
           }
            render(){
                return (
                   <div>
                    <h3>计数器{this.state.count}</h3>
                    <button onClick={()=>{this.add()}}>1</button>
                    </div>
                )
            }
       }
        //元素渲染
        ReactDOM.render(<Hello />,root)
    </script>
</body>

实现效果为:
在这里插入图片描述

2、Function.prototype.bind()

         利用ES5中的bind方法,将事件处理程序中的this与组件实例绑定到一起
代码如下:

<body>
    <div id="root"></div>
    <script type="text/babel">
        let root = document.getElementById('root')
       class Hello extends React.Component{
           constructor(){
               super()
               this.state = {
                   count:0
               }
               this.add = this.add.bind(this)//绑定
           }
           add(){
               this.setState({count:this.state.count+1})
           }
            render(){
                return (
                   <div>
                    <h3>计数器{this.state.count}</h3>
                    <button onClick={this.add}>1</button>
                    </div>
                )
            }
       }
        //元素渲染
        ReactDOM.render(<Hello />,root)
    </script>
</body>

实现效果为:
在这里插入图片描述

3、class 的实例方法

利用箭头函数形式的class实例方法
代码如下:

<body>
    <div id="root"></div>
    <script type="text/babel">
        let root = document.getElementById('root')
       class Hello extends React.Component{
           constructor(){
               super()
               this.state = {
                   count:0
               }
               this.add = this.add.bind(this)
           }
           add=()=>{
               this.setState({count:this.state.count+1})
           }
            render(){
                return (
                   <div>
                    <h3>计数器{this.state.count}</h3>
                    <button onClick={this.add}>1</button>
                    </div>
                )
            }
       }
        //元素渲染
        ReactDOM.render(<Hello />,root)
    </script>
</body>

实现效果同上,不在附图。

七、表单处理

1、受控组件

         我们知道,HTML 中的表单元素是可输入的,也就是有自己的可变状态,而React 中可变状态通常保存在 state 中,并且只能通过 setState() 方法来修改,那么,React将 state 与表单元素值value绑定到一起,最终由 state 的值来控制表单元素的值,这样就实现了变化的状态都保存在state中,并将其值受到 React 控制的表单元素称为受控组件。
在这里插入图片描述

1、受控组件的使用步骤

(1) 在 state 中添加一个状态,作为表单元素的value值(控制表单元素值的来源)

state = { txt: '' }
<input type="text" value={this.state.txt} />

(2)给表单元素绑定 change 事件,将 表单元素的值 设置为 state 的值(控制表单元素值的变化)

<input type="text" value={this.state.txt}
onChange={e => this.setState({ txt: e.target.value })}
/>

2、操作表单元素

例如操作文本框、富文本框、下拉菜单、复选框的值,示例如下:

<body>
    <div id="root"></div>
    <script type="text/babel">
        let root = document.getElementById('root')
        class App extends React.Component{
            constructor(){
                super()
                this.state = {
                    txt:'',
                    text:'',
                    sele:'xl',
                    isCheck:true
                }
            }
            handleChange = e=>{//文本框
                    this.setState({
                        txt:e.target.value
                    })
                }
            handleText = e=>{//富文本框
                this.setState({
                    text:e.target.value
                })
            }
            handleSele = e=>{//下拉菜单
                this.setState({
                    sele:e.target.value
                })
            }
            handleCheck = e=>{//复选框
               this.setState({
                isCheck:e.target.checked
               })
            }
            render(){
                return (
                   <div>
                    <input type="text" value={this.state.txt} onChange = {this.handleChange}/>
                    <br />
                    <textarea name="" id="" cols="30" rows="10" value={this.state.text} onChange={this.handleText}></textarea>
                    <br />
                    <select value={this.state.sele} onChange={this.handleSele}>
                        <option value="wh">小欢</option>
                        <option value="xl">小熊</option>
                        <option value="rc">小冉</option>
                        <option value="lj">小刘</option>
                        </select>
                    <br />
                    <input type="checkbox" value={this.state.isCheck} onChange={this.handleCheck}/>
                    </div>
                )
            }
        }
        //元素渲染
        ReactDOM.render(<App />,root)
    </script>
</body>

显示结果为:
在这里插入图片描述

3、多表单元素优化

         通过上例,我们可以看到每个表单元素都有一个单独的事件处理程序处理,使得我们的代码很太繁琐,我们可以对其进行优化,具体的实现方法是:使用一个事件处理程序同时处理多个表单元素

操作步骤为:
(1)给表单元素添加name属性,名称与 state 相同

<input type="text" name="txt" value={this.state.txt} onChange={this.handleForm}/>

(2)根据表单元素类型获取对应值

const value = target.type === 'checkbox' ? target.checked: target.value

(3)在 change 事件处理程序中通过 [name] 来修改对应的state

this.setState({[name]: value})

对上例进行优化,代码如下:

<body>
    <div id="root"></div>
    <script type="text/babel">
        let root = document.getElementById('root')
        class App extends React.Component{
            constructor(){
                super()
                this.state = {
                    txt:'',
                    text:'',
                    sele:'xl',
                    isCheck:true
                }
            }
            handleForm = e=>{//文本框
                //获取当前DOM对象
                const target = e.target
                //进行类型获取值
                const value = target.type==='checkbox'? target.checked:target.value
                //获取name
                const name = target.name
                    this.setState({
                        [name]:value
                    })
                }
            render(){
                return (
                   <div>
                    <input type="text" name='txt' value={this.state.txt} onChange = {this.handleForm}/>
                    <br />
                    <textarea name="text" id="" cols="30" rows="10" value={this.state.text} onChange={this.handleForm}></textarea>
                    <br />
                    <select name = 'sele' value={this.state.sele} onChange={this.handleForm}>
                        <option value="wh">小欢</option>
                        <option value="xl">小熊</option>
                        <option value="rc">小冉</option>
                        <option value="lj">小刘</option>
                        </select>
                    <br />
                    <input type="checkbox" name='isCheck' value={this.state.isCheck} onChange={this.handleForm}/>
                    </div>
                )
            }
        }
        //元素渲染
        ReactDOM.render(<App />,root)
    </script>
</body>

最终实现效果同上。

2、非受控组件

使用步骤:
(1) 调用 React.createRef() 方法创建一个 ref 对象

constructor() {
	super()
	this.txtRef = React.createRef()
}

(2) 将创建好的 ref 对象添加到文本框中

<input type="text" ref={this.txtRef} />

(3)通过 ref 对象获取到文本框的值

console.log(this.txtRef.current.value)

示例代码如下:

在这里插入代码片<body>
    <div id="root"></div>
    <script type="text/babel">
       class App extends React.Component{
           constructor(){
               super()
               //创建ref
               this.txtRef = React.createRef()
           }
           //获取文本框的值
           getTxt=()=>{
               console.log('文本框的值:',this.txtRef.current.value)
           }
           render(){
               return (
                   <div>
                        <input type="text" ref={this.txtRef} />
                        <button onClick={this.getTxt}>获取文本框的值 </button>
                    </div>
               )
           }
       }
        //元素渲染
        ReactDOM.render(<App />,root)
    </script>
</body>

实现效果为:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值