React16 基础
- 阐述
- JSX代码注释
- JSX中的class陷阱
- JSX中的html解析问题
- JSX中 `` 标签的坑
阐述
通过之前的教程作完“大宝剑”菜单后,如果你跟着我做出来了,说明你的React已经入门了。
也是一个好的开始,接下来的路虽然还很长,但会平坦的多。本文就讲一下JSX语法中需要注意的几个小坑。
JSX代码注释
JSX中的代码注释是非常有讲究的,这个书上介绍的也非常少,所以在这里讲一下,因为我在初学React在这里踩过坑。
我第一次写JSX注释,是直接这样写的,当然这样写是完全不对的。
<Fragment>
//第一次写注释,这个是错误的
<div>
<input value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
<button onClick={this.addList.bind(this)}> 增加服务 </button>
</div>
</Fragment>
那写JSX的注释,可以有下面两种写法:
<Fragment>
{/* 正确注释的写法 */}
<div>
<input value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
<button onClick={this.addList.bind(this)}> 增加服务 </button>
</div>
</Fragment>
如果你记不住,有个简单的方法,就是用 VSCode
的快捷键,直接按 Ctrl+/
,就会自动生成正确的注释了。
你可以把这个理解为,在JSX中写javascript代码。
所以外出我们套入了 {}
,然后里边就是一个多行的javascript注释。如果你要使用单行注释 //
,你需要把代码写成下面这样。
<Fragment>
{
//正确注释的写法
}
<div>
<input value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
<button onClick={this.addList.bind(this)}> 增加服务 </button>
</div>
</Fragment>
也就是你要进行换行,所以个人认为这种方法不太优雅,所以推荐第一种注释方法。
JSX中的class陷阱
比如要给朴素单纯的界面,加入黄色成分,让我们的文本框又粗又黄。
我们先来错误演示。
第一步:
先写一个CSS样式文件,在 src
目录下,新建一个style.css
的样式文件。
.input {border:3px solid #ae7000}
第二步:
在 Xiaojiejie.js
里引入,先用 import
进行引入,能用 import
引入,都是webpack
的功劳。
import './style.css'
第三部:
给JSX加入class
,注意下面的代码是错误的。
<input class="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
虽然现在页面是可以正常显示结果的,但是你打开浏览器控制台会发现Warning警告。
index.js:1437 Warning: Invalid DOM property `class`. Did you mean `className`?
in input (at Meinv.js:19)
in div (at Meinv.js:18)
in Xiaojiejie (at src/index.js:5)
意思就是要把 class
换成 className
,它是防止和 js
中的 class
类名 冲突,所以要求换掉。
这也算是一个小坑吧。
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>
上面的代码就可以实现 html
格式的输出。
style.css
.input {border:3px solid #ae7000}
Xiaojiejie.js
import './style.css'
Beauty.js
import React,{Component,Fragment } from 'react'
class Beauty extends Component{
//js的构造函数,由于其他任何函数执行
constructor(props){
//调用父类的构造函数,固定写法
super(props)
this.state={
inputValue:'<h1>willem</h1>' , // input中的值
//----------主要 代码--------start
list:['<h1>willem</h1>','基础按摩','精油推背']
//----------主要 代码--------end
}
}
render(){
return (
<Fragment>
<div>
<input className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
<button onClick={this.addList.bind(this)}> 增加服务 </button>
</div>
<ul>
{
this.state.list.map((item,index)=>{
return (
<li
key={index+item}
onClick={this.deleteItem.bind(this,index)}
dangerouslySetInnerHTML={{__html:item}}
>
</li>
)
})
}
</ul>
</Fragment>
)
}
inputChange(e){
// console.log(e.target.value);
// this.state.inputValue=e.target.value;
this.setState({
inputValue:e.target.value
})
}
//增加服务的按钮响应方法
addList(){
this.setState({
list:[...this.state.list,this.state.inputValue]
})
}
//删除单项服务
deleteItem(index){
let list = this.state.list
list.splice(index,1)
this.setState({
list:list
})
}
}
export default Beauty
JSX中
JSX中 <label>
的坑,也算是比较大的一个坑,label
是html
中的一个辅助标签,也是非常有用的一个标签。
先看下面的代码,我们在文本框前面加入一个<label>
。
<div>
<label>加入服务:</label>
<input className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
<button onClick={this.addList.bind(this)}> 增加服务 </button>
</div>
这时候想点击 “加入服务”
直接可以激活文本框,方便输入。
按照 html
的原思想,是直接加 ID
就可以了。
代码如下:
<div>
<label for="willem">加入服务:</label>
<input id="willem" className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
<button onClick={this.addList.bind(this)}> 增加服务 </button>
</div>
这时候你浏览效果虽然可以正常,但 console
里还是有红色警告提示的。
大概意思是不能使用 for
,它容易和 javascript
里的 for
循环混淆,会提示你使用 htmlfor
。
<div>
<label htmlFor="willem">加入服务:</label>
<input id="willem" className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
<button onClick={this.addList.bind(this)}> 增加服务 </button>
</div>
这时候代码就正确了,可以实现点击 <label>
后,激活 <input>
标签了。
这节算是我总结的一些JSX中的坑吧,总结出来,希望小伙伴们少踩这些坑,能快速上手React。
Beauty.js
import React,{Component,Fragment } from 'react'
class Beauty extends Component{
//js的构造函数,由于其他任何函数执行
constructor(props){
//调用父类的构造函数,固定写法
super(props)
this.state={
inputValue:'<h1>willem</h1>' , // input中的值
//----------主要 代码--------start
list:['<h1>willem</h1>','基础按摩','精油推背']
//----------主要 代码--------end
}
}
render(){
return (
<Fragment>
<div>
<label htmlFor="willem">加入服务:</label>
<input id="willem" className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
<button onClick={this.addList.bind(this)}> 增加服务 </button>
</div>
<ul>
{
this.state.list.map((item,index)=>{
return (
<li
key={index+item}
onClick={this.deleteItem.bind(this,index)}
dangerouslySetInnerHTML={{__html:item}}
>
</li>
)
})
}
</ul>
</Fragment>
)
}
inputChange(e){
// console.log(e.target.value);
// this.state.inputValue=e.target.value;
this.setState({
inputValue:e.target.value
})
}
//增加服务的按钮响应方法
addList(){
this.setState({
list:[...this.state.list,this.state.inputValue]
})
}
//删除单项服务
deleteItem(index){
let list = this.state.list
list.splice(index,1)
this.setState({
list:list
})
}
}
export default Beauty