React简单实例
1.基础页面搭建
首先在src
目录下新建一个Xiaojiejie.js
:
import React,{
Component} from 'react'
class Xiaojiejie extends Component {
render() {
return (
<div>
<div><input /><button>增加服务</button></div>
<ul>
<li>头部按摩</li>
<li>精油推背</li>
</ul>
</div>
)
}
}
export default Xiaojiejie
注意,在组件内容的最外层必须要有一个div标签包裹(组件外层包裹原则)。
<div> //最外层的div
<div><input /><button>增加服务</button></div>
<ul>
<li>头部按摩</li>
<li>精油推背</li>
</ul>
</div> //最外层的div
但是有时候无法添加外层包裹标签(例如使用flex布局时)时可以使用<Fragment></Fragment>
标签。
要使用<Fragment></Fragment>
标签先引入:
import React,{
Component,Fragment } from 'react'
接着将最外层的<div>
替换成<Fragment>
标签:
import React,{
Component,Fragment } from 'react'
class Xiaojiejie extends Component{
render(){
return (
<Fragment>
<div><input /> <button> 增加服务 </button></div>
<ul>
<li>头部按摩</li>
<li>精油推背</li>
</ul>
</Fragment>
)
}
}
export default Xiaojiejie
对index.js
进行修改:
import React from 'react'
import ReactDOM from 'react-dom'
import Xiaojiejie from './Xiaojiejie'
ReactDOM.render(<Xiaojiejie />,document.getElementById('root'))
2.响应式设计和数据的绑定
React
不建议你直接操作DOM元素,而是要通过数据进行驱动,改变界面中的效果。React
会根据数据的变化,自动的帮助你完成界面的改变。所以在写React
代码时,你无需关注DOM相关的操作,只需要关注数据的操作就可以了(这也是React
如此受欢迎的主要原因,大大加快了我们的开发速度)。
1.基本显示
现在要实现功能:在输入框中输入内容后点击增加服务按钮就可以将文本框中的内容添加到下方显示列表中。
先定义初始数据,定义在Xiaojiejie.js
组件中的构造函数里constructor
:
constructor(props) {
//构造函数
super(props) //调用父类方法
this.state = {
//所有的数据都放在this.state中
inputValue:'',
list:[]
}
}
接着进行数据绑定,跟Vue一样也是采用字面值
(我自己起的名字)的形式,就是使用{}
来标注,其实这也算是js代码的一种声明:
<input value={
this.state.inputValue} />
绑定完了之后就会发现文本框中的内容已经发生了变化。但是,我们此时无法手动进行更改,也就是说内容是定死的无法修改。接下去要进行绑定响应事件:
<input value={
this.state.inputValue} onChange={
this.inputChange} />
但此时还没有inputChange()
,需要自己在render()
方法的下面建立一个inputChange()
方法,代码如下:
inputChange (e) {
console.log(e.target.value); //打印输入的值
this.state.inputValue=e.target.value; //想要直接修改inputValue的值在这里是不行的
}
至于无法修改内容的原因:
- 一个是
this
指向不对,你需要重新用bind
设置一下指向(ES6的语法)。 - 另一个是React中改变值需要使用
this.setState
方法。
重新绑定this指向:
onChange={
this.inputChange.bind(this)}
使用this.setState
方法修改数据:
inputChange (e) {
console.log(e.target.value)
console.log(this)
this.setState({
inputValue:this.input.value
})
}
2.增加元素
目前页面的的两个li
标签还是写死的,要想可以进行增加删除操作,先将列表数据化(在构造函数中初始化数据),然后在页面上循环列表数据显示:
constructor(props) {
//构造函数
super(props) //调用父类方法
this.state = {
//所有的数据都放在this.state中
inputValue:'',
list:['基础按摩','精油推背']
}
}
import React,{
Component,Fragment } from 'react'
class Xiaojiejie extends Component{
render(){
return (
<Fragment>
<div><input /> <button> 增加服务 </button></div>
<ul>
{
this.state.list.map((item,index) => {
return <li key={
index+item}>{
item}</li>
// key={index+item} 为了避免出现警告
})
}
</ul>
</Fragment>
)
}
}
export default Xiaojiejie
最后就是实现增加列表数据的操作,在button上绑定事件:
<button onClick={
this.addList.bind(this)}>增加服务</button>
addList()
方法:
addList () {
this.setState({
list:[...this.state.list,this.state.inputValue],
// ...this.state.list 就相当于将列表中的初始数据再放入列表中,然后在后面再新增数据
//...是扩展运算符
inputValue:'' // 增加完之后清空输入框中的内容
},()=>{
console.log(this.ul.querySelectorAll('li').length)
})
}
3.删除元素
如果要删除一个东西,就要得到数组里的一个编号,这里指下标。传递下标就要有事件产生,先来给li
标签元素绑定一个删除元素事件,代码如下:
<ul>
{
this.state.list.map((item,index)=>{
return (
<li
key={
index+item}
onClick={
this.deleteItem.bind(this,index)}
>
{
item}
</li>
)
})
}
</ul>
然后编写deleteItem()
方法实现删除元素,先声明一个局部变量,然后利用传递过来的下标,删除数组中的值.删除后用setState
更新数据就可以了:
deleteItem(index){
let list = this.state.list //先声明一个局部变量
list.splice(index,1)
this.setState({
list:list
})
}
先声明一个局部变量的原因:
React
是禁止直接操作state
的,虽然直接操作功能可以实现,但是在后期的性能优化上会有很多麻烦。所以还是申明局部变量来修改。
3.JSX语法踩坑
1.语句注释
不同于Javascript
的注释://注释
JSX的语句注释格式为:
{/* 注释 */}
或者
{
//注释
}
如果是在
vscode
中可以直接用Ctrl+/
快速生成注释格式。
2.class类名问题
在给元素添加css
样式的时候为了避免DOM
的class
与js
中的class类名
冲突,要把class
换成className
。例如:
下面这种写法是不对的:
<input class="input" value={
this.state.inputValue} onChange={
this.inputChange.bind(this)} />
这样写才对:
<input className="input" value={
this.state.inputValue} onChange={
this.inputChange.bind(this)} />
3.JSX中的html标签解析问题
如果想在文本框里输入一个<h1>
标签,并进行渲染。默认是不会生效的,只会把<h1>
标签打印到页面上,因此可以使用dangerouslySetInnerHTML
属性来解决。用法如下:
<ul>
{
this.state.list.map((item,index)=>{
return (
<li
key={
index+item}
onClick={
this.deleteItem.bind(this,index)}
dangerouslySetInnerHTML={
{
__html:item}}
>
</li>
)
})
}
</ul>
4.
初始代码如下:
<div>
<label>加入服务:</label>
<input className="input" value={
this.state.inputValue} onChange={
this.inputChange.bind(this)} />
<button onClick={
this.addList.bind(this)}> 增加服务 </button>
</div>
如果想点击“加入服务”直接可以激活文本框,方便输入:
<div>
<label for="jspang">加入服务:</label>
<input id="jspang" className="input" value={
this.state.inputValue} onChange={
this.inputChange.bind(this)} />
<button onClick={
this.addList.bind(this)}> 增加服务 </button>
</div>
但是这样浏览器会出警告:不能使用for
.它容易和javascript
里的for
循环混淆,会提示你使用htmlfor
。
<div>
<label htmlFor="jspang">加入服务:</label>
<input id="jspang" className="input" value={
this.state.inputValue} onChange={
this.inputChange.bind(this)} />
<button onClick={
this.addList.bind(this)}> 增加服务 </button>
</div>
4.React插件Simple React Snippets
在vscode插件中搜索Simple React Snippets
并安装,完事之后可以更方便的敲代码:
- 快速引入:输入
imrc
即可生成:
import React, {
Component } from 'react';
- 快速生成类:输入
cc
即可生成:
class extends Component {
state = {
}
render() {
return ( );
}
}
export default ;