React.js是前端三大框架angular.js,React.js,Vue.js之一。这三大框架有很多理念是相同的,但是也有各自的特点
React起源于facebook的内部项目,因为该公司对市场上所有javaScript MVC框架都不蛮子,就决定自己写一套,用来假设instagram的网站。做出来以后,发现这套东西很好用,于是就与2013年5月开源了。
React可以作为一个js库来使用,我们在页面上引用相关的js文件,就可以使用它来做一些页面效果。
React可以将界面拆分成一个个组件,通过组件来构建界面,然年后用自动化工具来生成单页面(SPA-single page application)应用系统
首先通过将React作为一个js库来使用,以便于学习React的一些基本概念,在页面上引入已经下载好的三个js文件,就可以使用React了。
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin>script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin>script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js">script>
其中。前两个js文件时React的核心文件,第三个js文件是转换编译器,它能将ES6语法以及JSX语法转换成可以在浏览器中
运行的代码。
<div id="root">div>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, World!</h1>,
document.getElementById('root')
)
script>
上面编写的不是真正的JavaScript代码,因为上面是JavaScript和html的混合,所以它的类型需要写成text/babel,最终通过编译器编译成浏览器可以执行的js
jsx语法是一种类似于html标签的语法,它的作用相当于让我们在JavaScript代码中直接写html代码,但是jsx不完全是html,它是JavaScript的一种扩展语法,它具有JavaScript的全部能力。可以在jsx代码中插入变量或者表达式,用jsx语法写出来的语句是一个对象,我们可以将它存为一个变量,这个变量作为ReactDOM对象的render方法的第一个参数。
let el = <h1>Hello world!</h1>;
ReactDOM.render(
el,
document.getElementById('root')
)
jsx的结构还可以写的更复杂,可以是嵌套结构。如果是嵌套结构,需要有唯一的一个外层标签。标签中如果是单个标签要在结尾加"/“例如
.在jsx中可以通过”{}"插入变量,表达式或者是函数调用。
<script type="text/babel">
let iNum01 = 10;
let sTr = 'abcdefghijk';
function fnRev(s){
return s.split(''),reverse().join('');
}
let el = (
<div>
<h3>jsx语法</h3>
{/* 插入变量及运算 */}
<p>{ iNum01 +5 }</p>
{/* 插入表达式 */}
<p>{ sTr.Split('').reverse().join('') }</p>
{/* 插入函数调用 */}
<p>{ fnRev(sTr) }</p>
{/* 插入三元运算表达式 */}
<p>{ ok?'YES':'NO' } </p>
</div>
);
ReactDOM.render(
el,
document.getElementById('root')
)
</script>
jsx中指定标签的属性值建议用双引号,引号必须有。属性名建议用驼峰式,其中class属性需要写成className,属性值如果是可变的,也可以写成'{}'的形式,里面可以和上面写法一样。标签如果是单个的,在结尾一定要"/"
{/* 定义class */}
<p className="sty01">使用样式</p>
{/* 单个标签,结尾要加"/" */}
<img src={user.avatarUrl} />
组件可以理解成是一个组成页面的部件或者零件。每个部件都有自己完整的结构和功能。多个部件拼装在一起可以组成一个页面,从组件的实现来看。组件最终是要返回一个jsx对象。不过它和jsx对象的区别是,它在jsx对象的基础上。还带有自己的方法和属性。能完成它自己的交互功能。组件有两种定义方式:一种是函数式定义。一种类定义。
通过函数定义一个组件。组件名称首字母要大写。函数接受一个参数props,返回一个jsx对象。其中name属性是在渲染组件·时,通过定义属性传入进来的。
function welcome(props) {
return <h1>Hello ,{props.name}</h1>;
}
定义的类都要继承于React对象中的component类。
class Weclome extends React.Component {
render(){
return <h1>Hello,{this.props.name}</h1>;
}
}
组件渲染和jsx对象一样。通过ReactDOM.render()方法来渲染组件
function Welcome(props) {
return <h1>Hello,{props.name}</h1>;
}
const element = <Weclome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
可以在一个组件内,拼装其他组件,从而组合成一个更大的组件
function Weclome(props) {
return <h1>Hello,{props.name}</h1>;
}
function App(){
return (
<div>
<Welcome name="Sara" />
<Welcome name="Atlan" />
<Welcome name="Edite" />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
React绑定事件和JavaScript中的行间事件类似。事件绑定是写在标签中的。但是React事件是在原生事件的基础上做了封装。它的事件使用驼峰命名。而不是全部小写。事件需要传递一个函数作为事件处理程序。 通过类定义组件,将这个函数作为一个方法定义在组件中。
定义一个点击弹出名称的组件
class Helloname extends React.Component {
fnHello(){
alert('Hello,Tom');
}
render() {
return (
<input type="button" value="打招呼" onClick={this.fnHell0} />
)
}
}
ReactDOM.render(<Helloname />,document.getElementById('root'));
传递名称参数
class Helloname extends React.Component {
fnHello(){
alert(this.props.name);
}
render(){
return (
<input type="buttion" value="打招呼" onClick={this.fnHello.bind(this)}/>
)
}
}
ReactDOM.render( <Helloname name="Tom" />, document.getElementById(''root'));
按钮在调用方法时,this默认会指向这个按钮,所以在绑定事件时,需要绑定this。将this指向当前对象。
组件如果需要定义默认属性并且默认属性还是可变的。这个就是组件的状态属性了。状态属性默认名称state。这个属性需要在组件定义是初始化。所以我们需要使用类的构造函数来对这个属性进行初始化。
定义一个点击按钮数字递增的
class Increase extends React.Component {
constructor(props){
super(props);
this.state = {iNum:10};
this.fnAdd = this.fnAdd.bind(this);
}
fnAdd(){
//使用setState来改变state中的值
this.setState(prevState=>({
iNum:prevState.iNum+1
}));
}
render(){
return (
<div>
<p> {this.state.iNum}</p>
<input type="button" onClick={this.fnAdd} value="递增" />
</div>
);
}
}
ReactDOM.render(
<Increase />,
document.getElementById('root')
);
state注意点
1.不能直接修改state的值,应该用setState代替
// 下面写法是不会更新组件,是错误的
this.state.iNum = 11;
//应该写成setState的形式
this.setState({iNum:11});
2.state的值可能是异步的。如果需要在state的值的基础上修改得到新的值,可以使用函数的形式。函数的参数中传递的一个参数是state上一个状态的值。可以在这个值基础上修改。prevState代表state上一个状态的值。
this.setState(prevState=>({
iNum:prevState.iNum+1
}));
可以将数组中的数据通过数组遍历渲染成一个jsx对象,在通过React渲染这个对象就可以了。
let aList = ['红海','陆海','三元','王五']
let el = aList.map((item,i)=>
<li key={i}>{item}</li>
);
ReactDOM.render(
<ul>{el}</ul>,
document.getElementById('root')
);
通过map方法遍历数组中的成员,map方法的第二个参数是数组中的索引值,在循环生成li结构时。需要给每个li加上一个key。这个key的值可以用数组中的成员索引值。
表单元件对应着数据。而且数据都是变化的,所以我们会将表单元件的数据对应于组件中的state值。让它们之间的值实现双向数据绑定的效果。要实现这个效果。需要在表单元件上绑定onchange事件,来将state中的值改变为表单元件中的值,同时也需要将表单的value属性值,设置为等于state中的属性值.
表单数据绑定示例
class Myform extends React.Component {
constructor(props){
super(props);
this.state={
uname:''
};
}
//ev指的是系统自动产生的事件对象
//ev.target指的说发生事件的元素
fnNameInput(ev){
this.setState({
uname:ev.target.value
}
)
}
render(){
return (
<form>
<p>昵称:{this.state.uname}</p}
<input type="text" value={this.state.uname} onChange={this.fnNameInput.bind(this)} />
</form>
);
}
}
ReactDOM.render(
<Myform />,
document.getElementById('root')
);
生命周期方法,指的是在组件初始化,以及组件销毁时,会自动执行的两个方法。可以在初始化方法中执行获取数据的操作。在组件销毁方式中执行一些清楚操作。比如清楚定时器等操作。这两个方法分别是:componentDidMount和componentWillUnmount
使用示例
class Hello extends React.Component{
constructor(props){
super(props);
this.state = {}
}
//组件初始化时自动执行的方法
componentDidMount(){
console.log('componentDidMount');
}
// 组件销毁时自动执行的方法
componnentWillUnmount(){
console.log('componentWillUnmount');
}
render(){
return (
<h1>Hello world!</h1>
);
}
}
ReactDOM.render(<Hello />,document.getElementById('root'));
setTimeout(() => {
ReatDOM.render(<h1>切换组件</h1>,document.getElementById('root'));
},2000};
React没有集成ajax功能,要使用ajax功能,可以使用官方推荐的axios.js库来做ajax的交互。地址:https://github.com/axios/axios/releases
axios完整写法
axios({
url: '/login/',
method:'get',
responsetypr:'json',
params:{
firstName: 'Fred',
lastName: 'Flintstone'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
常用参数
1.url 请求地址
2.method 请求方法,默认是GET
3.responsetype 设置返回数据的格式,常用’json’格式
4.params 发送给服务器的数据
5.then 请求成功后的回调函数
6.catch 请求失败后的回调函数
简写
axios.get('/login',{
params: {
ID:12345
}
})
.then(function (response) {
console.log(responese);
})
.catch(function (error) {
console.log(error);
});
{/* post请求 */}
axios.post('/login',{
params: {
ID:12345
}
})
.then(function (response) {
console.log(responese);
})
.catch(function (error) {
console.log(error);
});