渲染react的两种方法,render只能对单个进行渲染
ReactDOM.render(<App />,document.getElementById('root'))
ReactDOM.render(
<div>
<App />
<Text />
</div>,
document.getElementById('root')
)
JSX
JSX语法里面,有两种类型的标签
第一种标签:普通的html标签
第二种标签:组件标签
组件的标签的首字母必须是大写的,普通的为小写,比如说< div>
TodoList的添加删除
import React ,{Component, Fragment} from 'react';
//react 响应式
//定义组件
class TodoList extends Component{
//constructor 在组件创建的第一个时刻自动被执行
//组件会接收外部传的参数,把这个参数传递给外部基类的构造函数
//前两行固定写法
constructor(props){
super(props);
//在组件中创建了两个数据,数据一定要定义在state中
this.state = {
inputValue:'',
list:[]
}
}
handleInputChange(e){
// console.log(e.target.value);
// this.state.inputValue = e.target.value;不能直接这么改,会出错,使用固定的setState函数
this.setState({
inputValue:e.target.value
})
}
handleKeyUp(e){
// console.log(e.keyCode);
//回车的keyCode值为13
if(e.keyCode===13){
//this.state.inputValue;
//list中包含了list和input中的量
const list = [...this.state.list,this.state.inputValue];
//es6中如果键和值都是一样的,list:list 可以直接写list
this.setState({
list,
inputValue:''
})
}
}
handleItemClick(index){
//拿到当前数据,拷贝一个副本
const list = [...this.state.list];
list.splice(index,1);
this.setState({list});
}
//render函数决定组件渲染内容
render(){
//在render函数中,this指向的是这个组件
//return一个内容出去,如果没有return出去,页面上是没有内容的
return(
<Fragment>
{/* 对于jsx语法,一个属性等于一个js变量或者一个js表达式,需要用{}引起来 */}
<input
value = {this.state.inputValue}
// handleInputChang函数的this指向的是undefined,需要使用bind将this指向变更成这个组件的指向,
// 也就是指向render()函数的指向,又由于render函数指向的是组件,也就是说handleInputChange也指向了这个组件
onChange = {this.handleInputChange.bind(this)}
//当按任意一个键,键弹起来的时候绑定的事件
onKeyUp = {this.handleKeyUp.bind(this)}
/>
<ul>
{
// 用map进行循环输出
// map方法必须进行return
this.state.list.map((value,index)=>{
// 加入key会使react的性能更高,key值是唯一的
// 循环输出的每一项都要使用key,值不使用key会一直进行报警告
return (
<li
key={index}
onClick = {this.handleItemClick.bind(this,index)}
>
{value}
</li>)
})
}
</ul>
</Fragment>
);
}
}
//在index引用之前要先将totolist暴露出去
//也就是把自己暴露出去,供别人使用
export default TodoList;
bind(this)底层原理:每一次用户触发这个事件的时候,都会给你重新生成一个新的函数,这样会导致性能较低。
随后将this.handleInputChange.bind(this);
放入constructor构造函数中,因此这个方法只在组件创建的一瞬间被执行一次,之后这个函数handleInputChange
就不会被新的生成了
JSX中不能有class会和类名class相冲突,因此为了防止这种警告,使用className
从前使用点击一个标签使输入框聚焦,使用lable for
但是在JSX语法中,for是一个循环的关键字,又会有歧义,可能会有冲突,因此在JSX语法中使用htmlFor
注释
// 这是普通js中的注释
{/*这是JSX在的注释*/}
进一步完善
import React ,{Component, Fragment} from 'react';
import './style.css'
//react 响应式
//定义组件
class TodoList extends Component{
//constructor 在组件创建的第一个时刻自动被执行
//组件会接收外部传的参数,把这个参数传递给外部基类的构造函数
//前两行固定写法
constructor(props){
super(props);
this.handleInputChange = this.handleInputChange.bind(this);
this.handleKeyUp = this.handleKeyUp.bind(this);
//在组件中创建了两个数据,数据一定要定义在state中
this.state = {
inputValue:'',
list:[]
}
}
handleInputChange(e){
// console.log(e.target.value);
// this.state.inputValue = e.target.value;不能直接这么改,会出错,使用固定的setState函数
this.setState({
inputValue:e.target.value
})
}
handleKeyUp(e){
// console.log(e.keyCode);
//回车的keyCode值为13且内容不为空
if(e.keyCode===13 && e.target.value!==''){
//this.state.inputValue;
//list中包含了list和input中的量
const list = [...this.state.list,this.state.inputValue];
//es6中如果键和值都是一样的,list:list 可以直接写list
this.setState({
list,
inputValue:''
})
}
}
handleItemClick(index){
//拿到当前数据,拷贝一个副本
const list = [...this.state.list];
list.splice(index,1);
this.setState({list});
}
getListItems(){
// 用map进行循环输出
// map方法必须进行return
return this.state.list.map((value,index)=>{
// 加入key会使react的性能更高,key值是唯一的
// 循环输出的每一项都要使用key,值不使用key会一直进行报警告
return (
<li
key={index}
onClick = {this.handleItemClick.bind(this,index)}
// 不进行转译,比如<h1>test</h1>输出的是大字号的test,而不是<h1>test</h1>
//对value的内容不要做转译,直接的输出到li标签的内部
//{__html:value}是js的一个对象,html前面是两个下划线
dangerouslySetInnerHTML={{__html:value}}
>
</li>
)
})
}
//render函数决定组件渲染内容
render(){
//在render函数中,this指向的是这个组件
//return一个内容出去,如果没有return出去,页面上是没有内容的
return(
<Fragment>
{/* 对于jsx语法,一个属性等于一个js变量或者一个js表达式,需要用{}引起来 */}
{/* <span>请输入内容:</span> */}
<label htmlFor ='myinput'>请输入内容:</label>
<input
id = 'myinput'
className = 'input'
value = {this.state.inputValue}
// handleInputChang函数的this指向的是undefined,需要使用bind将this指向变更成这个组件的指向,
// 也就是指向render()函数的指向,又由于render函数指向的是组件,也就是说handleInputChange也指向了这个组件
onChange = {this.handleInputChange}
//当按任意一个键,键弹起来的时候绑定的事件
onKeyUp = {this.handleKeyUp}
/>
<ul>
{this.getListItems()}
</ul>
</Fragment>
);
}
}
//在index引用之前要先将totolist暴露出去
//也就是把自己暴露出去,供别人使用
export default TodoList;