一、React基础
1、使用方法
通过JavaScript标签引用reactjs
特点:古老方式,js比较大需要拆分加载很多js标签文件,性能低维护差
通过脚手架工具开发
特点:通过脚手架工具编译后的代码才能在浏览器运行
官方脚手架工具:Create-react-app
2、脚手架文件结构
create-react-app 项目名//创建目录
//文件入口在src中的index.js,react编写的页面样式css在该文件中导入即可,类似于路由入口,负责将编写的react代码放置指定的标签中,还有css文件
//public目录中的index.html是页面模板,body标签中id为root的标签为最终插入的位置,可自行修改或着拆分多个标签的组合
//App.js导入到index.js再导入到index.html渲染出页面
//App.js中也可以导入css文件、图片文件等,最后都会渲染出来
//index中在固定id的标签中插入的App就是组件
ReactDOM.render(<App />, document.getElementById('root'));
3、组件定义
import React,{Component} from 'react';//如果没有大括号及内容得话Component得应用必须使用React.Component来调用
//JSX语法需要导入React包才可以编译
class App extends Component {//App继承了Component,成为一个react组件
render(){//组件展示得内容为render得返回内容
return(
<div>
hello word
</div>
);
}
}
//JSX语法出现在render(){return(继承对象的方法的返回值中);}或者ReactDOM.render(参1,参2)的参1中
4、JSX语法
在js文件中写标签就是JSX语法,JSX语法中自定义标签<App/>
首字母必须大写,小写字母一般都是原生html标签。JSX语法中单标签必须在末尾的尖括号前加/
render()
返回得标签必须是一个标签包裹得多标签,不能返回多个并列标签
react16
中如果想要包裹多标签需要多引入Fragment
import React,{Component,Fragment} from 'react';
<Fragment></Fragment>//使用该标签包裹多标签即可
5、constructor构造函数
class Todolist extends Component{
constructor(props){//构造函数 类中必有得方法,最优先执行
super(props);//先调用父类的构造函数,,继承父类并改写
this.state={//组件的状态,用于定义react数据
inputValue:'';//写死后就不会再变化
}
}
//如果在JSX中使用JS的变量或表达式,需要加{}
//将状态中的变量和标签绑定,状态变化value就跟着变化
render(){//标签中的class属性与类的名称一样,避免冲突需要使用className替代
<div className='input'>
<input value={this.state.inputValue}
onChange={this.handleInputChange.bind(this)}
/>
</div>
}//react中绑定事件时onClick等事件的首字母必须大写
handleInputChange(e){//需要定义才可以使用,接收的是event对象
//会出现this指向错误undefined,需要调用时绑定this对象
//target是事件的Dom对象(发生事件的标签),value是标签的属性
//this.state.inputValue=e.target.value
//想要修改state中的数据必须调用规定的setState()方法
this.setState({
inputValue:e.target.value
})
}
}
//在JSX中遍历数组生成标签
this.state.list.map((item,index)=>{
return <li>{item}</li>
})
//JSX中{/*注释写法*/}或
{
//注释
}
//注意:任何地方要修改this.state中的数据都要用setState方法才可以!!!
<lable for="inputid"></lable>//lable扩大input的点击范围,为避免冲突使用htmlFor替代
<input id="inputid" />
//标签属性dangerouslySetInnerHTML={{__html:变量名}}可以将变量 里的html标签按照html语法展示出来放入标签HTML内容中
6、拆分组件
//在JXS中可以导入子组件,并将参数传递过去,可以传递方法
//注意传递方法的时候必须要绑定父组件的this,否则子组件调用时this指定的是子组件的方法,在子组件中找不到该方法
<TodoItem content={item} handleItemDelete = {this.handleItemDelete.bind(this)}/>
//在子组件可以通过this.props.content来使用传递过来的参数,或者方法。
//子组件要修改父组件的内容,必修调用父组件的方法,可以通过上面方法将参数及方法传递过去
constructor(props){
super(props);
//为了方便管理,在标签点击等事件调用函数避免this指向错误,会将this绑定放在构造函数中统一管理,能够提高性能。下面就可以直接调用。
this.handleClick = this.handleClick.bind(this)
}
//在块中使用const {content,handleItemDeltete}=this.props 注意:props是一个结构,结构赋值content也需要是一个结构才能对应,在jXS语法中,变量要用{this.props} 阔起来
//那么在下面写的地方就可以直接使用content代替this.props.content了。
//在JSX语法中注意划分页面代码和逻辑代码,将逻辑代码提出来然后完整的return回去就能将代码分类。
getTodoItem(){
return this.stat.list.map((item,index)=>{
return (
<div></div>
)
})
}
7、新版this.setState使用
新版中的this.setState可以接收函数
const value = e.target.value
this.setState(()=>{
return{
inputValue:e.target.value
}
})
//eas6语法可以这样写
this.setState( ()=>({inputValue:value}))
//把对象变成函数的时候成异步的了
//这里需要在外部定义value将e.target.value的值储存
//PrevState代表前一个状态的this.state的数据,props代表当前状态的值
this.setState( (PrevState,props)=>({ }) )
//通过PrevState.list就可以使用该次修改前的数据,可以避免修改他的状态
{list:list}可以省略为{list}
//如果JSX有循环语句需要给循环语句内最外层标签添加key值,防止报错,方便调取
8、react和其他框架的混用
react只是渲染指定标签的内容其他标签的内容可以使用其他框架进行渲染,只要负责的标签不同就不会相互影响。
9、组件间数据传递及修改(每个组件中的数据只能通过该组件的方法进行修改)
普通标签小写,组件标签都是大写开头
父组件更改子组件可以通过传值来实现,子组件改父组件可以通过父组件传递过来的方法对父组件进行修改。父组件传递过来一个关于setState的方法就能通过传参调用该方法修改父组件的state内容,注意绑定this。
父组件传递给子组件的值是不能够修改的,只能读取使用。react数据是单向数据流传递,子组件不能影响父组件。
跨级修改光用react框架解决该问题会使项目变得很复杂,需要使用其他数据型框架(redux等)解决该问题,react只解决视图层的问题,传值问题由其他框架解决。小型项目可以减少树状层数来减少数据传递问题。
10、PropTypes与DefaultProps 类型
import PropTypes from 'prop-types'
TodoItem.propTypes={
content:PropTypes.string.isRequired,//末尾代表父组件必须要传字符串的值,否则警告
deleteItem:PropTypes.func,
index:PropTypes.number
}//对类型进行强校验,如果不符合控制台会有警告
TodoItem.defaultTypes={//如果test没有传递使用默认值代替
test:'hello word'
}
11、Props,State与render函数关系(react由数据驱动的框架)
render函数在state或props状态每发生变化之后会自动执行一次更新数据。
state是组件自己的,props是父组件传递过来的。
父组件的render运行后所有子组件的render都将会运行一次。