3.组件的基本用法

目录

1  创建组件

1.1  用函数创建组件

1.2  使用类创建组件

2  项目上组件的使用方式

3  事件处理

3.1  事件绑定

3.1.1  类组件绑定事件

3.1.2  函数组件绑定事件

3.2  事件对象

4  组件状态

4.1  初始化状态

4.2  获取状态

4.3  设置状态

4.3.1  箭头函数

4.3.2  重新绑定this

5  表单处理

5.1  受控组件

5.1.1  input

5.1.2  textarea

5.1.3  select

5.1.4  checkbox

5.1.5  多表单元素优化

5.2  非受控组件

6  发表评论案例


1  创建组件

1.1  用函数创建组件

创建组件的函数名称必须以大写字母开头,小写会报错导致不能成功渲染,原因是你发现html的标签首字母都是小写的,你自定义组件用大写有个区分

创建组件的函数必须有返回值,不写不行,至少要写成 return null 才不会报错

定义的时候把jsx写在return中,用的使用使用以函数名相同的标签就行了,我下面的是双标签,你也可以使用单标签

一般来讲我们不会使用箭头函数作为创建组件的函数,但箭头函数可以创建组件

1.2  使用类创建组件

用关键字class定义一个类 My_components 用关键字extends继承 React.Component

  • 自定义组件需要以大写字母开头
  • 需要有render(),render()中需要有return

2  项目上组件的使用方式

一般来讲每一个组件都会独占一个JS文件,之后会有一个文件夹放所有的组件JS文件,我们下面做个例子

首先在src中创建一个文件夹Components,然后在Components中创建一个JS文件,这个JS文件的名字就是组件的名字

之后在My_components.js中创建组件,然后导出

之后进入index.js,引用后就可以渲染了

用函数定义的组件也可以像上面一样导出,index.js代码不变

3  事件处理

3.1  事件绑定

3.1.1  类组件绑定事件

  • this.something就是上面定义的something函数,如果你直接在onClick后的大括号中写console.log(1),那么在运行一开始就会被执行,且后面再点击是无效的
  • React事件采用驼峰命名法,onClick是点击事件,onMouseEnter是鼠标移动到元素上触发的事件

按照上面的代码后点击了3次,发现可以成功绑定事件

3.1.2  函数组件绑定事件

打开后点了三下

3.2  事件对象

React中的事件对象叫做合成事件或合成事件对象,可以兼容所有浏览器

给事件处理函数一个形参就可以拿到事件对象

用法和原生JS的事件对象用法相似,比如可以获取 pageX.pageY,e.preventDefault()可以阻止浏览器的默认行为(比如a标签的跳转页面)

4  组件状态

用函数创建的组件叫无状态组件,用类创建的组件叫有状态组件,状态(state)就是数据,比如说组件是否被勾选了这种就叫状态。

当我们只需要展示数据的时候我们用函数组件,需要交互的时候我们用类组件

我们通过 state 获取状态,通过 setState() 设置状态,state的值是对象,其中包含多组键值对,这些键值对在默认情况下只能在组件内部使用(通过组件通讯可以给其他的组件使用)

4.1  初始化状态

我们可以这样初始化state,其中constructor(),super(),this.state的名称都是固定的,count及后面的值是自定义的

也可以这样初始化state,一般来讲会用下面这种,写起来比较方便

4.2  获取状态

可以使用this.state拿到状态,我们搞一下看看

4.3  设置状态

不能直接操作this.state.count,比如用等于号进行赋值,对列表push这些操作,直接进行这些操作会报错。想要设置状态要使用this.setState()进行修改

设置状态后会对组件的渲染结果产生影响,如果我们想改变组件的一些内容,我们只需要对state进行修改就可以了

这样写会有this的指向问题

点击按钮后会报错,报错的原因是不能读取 undefined属性的setState属性,也就是说此时在add_one()中的this是undefined

可以用下面两种方法解决this指向的问题

4.3.1  箭头函数

箭头函数自身不绑定this,如果写了this默认为箭头函数外一层的this,也就是你定义的组件

点三下发现没问题,既改变了state中的count,又更新了UI

也可以这样写,这样写的this指向的是render()的this,render()的this就是组件的this

还可以这样写,这样写就给this传进来了,this就不再是undefined了

4.3.2  重新绑定this

也可以对this进行重新绑定

重新绑定后可以正常使用了

5  表单处理

5.1  受控组件

5.1.1  input

定义一个状态的变量something,然后把原本的value交给这个变量something来管理,之后定义onChange事件,每一次输入框内容改变的时候都会将文本框中的内容赋值给变量something

  • something是自定义的变量,名称自定
  • 调整完上面说的后,此时input受React控制,我们称input为受控组件

5.1.2  textarea

textarea除了改了个标签名,剩下没有变化

5.1.3  select

select有一些区别

由于我们给了默认值,所以刚打开页面的时候,就会以默认值渲染

选择其他选项后点击按钮可以正常获取信息

5.1.4  checkbox

checkbox需要将value改成checked,变量定为布尔量

打开后会渲染指定的状态

也可以获取目前的状态

5.1.5  多表单元素优化

每用一个表单元素都得需要一个变量存储状态的值,再加上一个处理程序修改值,那样会有很多个处理程序,很麻烦

我们简单做个判断,如果类型是checkbox就拿checked属性,如果不是就拿value属性,然后给每一个表单元素一个name,name与state中的状态名称相同

点击按钮后可以获取当前状态

5.2  非受控组件

这种方式不常用,看别人写了能懂就行

使用ref对象,ref全称是reference,React中的ref对象是操作DOM用的

6  发表评论案例

打开是这样的

输入评论人和评论内容后点击发表可以把内容显示在下面

全部代码 

class My_components extends React.Component {
    state = {
        username:"",
        remark:"",
        remark_list:[],
        // remark_list:[{username:1,remark:2,remark_id:0},{username:1,remark:3,remark_id:1}],
        remark_id:""
    }

    publish_remark = ()=>{
        if (this.state.username.trim() && this.state.remark.trim()) {
            this.setState({remark_id : this.state.remark_list.length},() => {
                const new_remark_list = [{...this.state,remark_id:this.state.remark_id},...this.state.remark_list]
                this.setState({remark_list : new_remark_list,username : "",remark : ""})
            })
        }
    }

    form_change = (e) => {
        const value = e.target.type==='checkbox'?e.target.checked:e.target.value
        this.setState({[e.target.name]:value})
    }

    load_remark = () => {
        if (this.state.remark_list.length === 0) {
            return <div>暂无评论,快去评论吧~</div>
        }
        else {
            return (
            <ul>
                {this.state.remark_list.map(item => <li key={item.remark_id}>评论人:{item.username} 评论内容:{item.remark}</li>)}
            </ul>
            ) 
        }
    }

    render() {
        return (
            <div>
                <input type="value" placeholder= "请输入评论人" name='username' value={this.state.username} onChange={this.form_change}></input>
                <br></br>
                <textarea placeholder= "清输入评论内容" name='remark' value={this.state.remark} onChange={this.form_change}></textarea>
                <br></br>
                <button onClick={this.publish_remark}>发表评论</button>
                {this.load_remark()}
            </div>
        )
    }
}

ReactDOM.createRoot(document.querySelector('div')).render(<My_components></My_components>)

这里的这个地方是一个回调函数,在JS中执行顺序与书写顺序不一定一致,我需要首先定义一个id,然后再给id,所以定义id一定在给id的代码之前

由于不能对状态直接进行操作,所以我们要新搞一个变量 new_remark_list 来覆盖掉之前的 remark_list

其中三个点的意思是继承指定变量的所有内容,这三个点可以用于对象也可以用于列表,如果用于列表可以选择将之前的内容放在前面还是放在后面,我下面的图是放在后面,如果写 [...this.state.remark_list,{...this.state,remark_id:this.state.remark_id}] 就是将之前的内容放在新列表的前面

可以直接返回html标签,然后在render()中直接使用函数进行渲染

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Suyuoa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值