一、准备工作
首先通过将React作为一个js库来开发,来学习React的一些基本概念,在页面上要引入已经下载好的三个js文件,就可以使用React。
<script src="js/react.development.js"></script>
<script src="js/react-dom.development.js"></script>
<script src="js/babel.min.js"></script>
其中,前两个js文件是React的核心文件,第三个js文件是一个转换编译器,它能将ES6语法及jsx语法转换成可以在浏览器中运行的代码。
二、JSX语法
jsx语法是一种类似于html标签的语法,他的作用相当于是让我们在JavaScrip代码中直接写html代码,但是jsx不完全是html,它是JavaScript的一种拓展语法,它具有JavaScript的全部能力,我们还可在jsx代码中插入变量或者表达式,用jsx语法写出来的语句是一个对象,我们可以将它存为一个变量,这个变量作为ReactDOM对象的render方法的第一个参数。
<div id="root"></div>
let el = <h1> Hello world!</h1>;
ReactDOM.render(
el,
document.getElementById('root')
)
jsx 的结构还可以写的更复杂,可以是嵌套结构,如果是嵌套结构,需要有唯一的一个外层标签,标签中如果是一个单个的标签,在结尾要加上”/“,在jsx中可以通过"{}"插入变量,表达式或者函数调用。
<script type="text/babel">
let iNum01 = 10;
let sTr = 'abcdefgh123456';
let ok = false;
let url = 'http://www.baidu.com'
function fnRev(s){
return s.split('').reverse().join('');
}
let el = (
<div>
<h2>jsx语法</h2>
{/* jsx里面的注释 */}
<p>{ iNum01+5 }<p> {/*插入变量及运算*/}
<p>{ sTr }</p>
<p>{ sTr.split('').reverse().join('') }</p> {/*插入表达式*/}
<p>{ sTr }</p>
<p>{ fnRev(sTr) }</p> {/* 通过调用函数进行反转 */}
<p>{ ok?'YES':'NO' }</p>
<a href={url} className="sty01">这是一个链接</a>
</div>
);
ReactDOM.render(el,document.getElementById('root') );
</script>
三、组件和属性(props)
组件可以理解为是一个组成页面的部件或者是零件,每个部件都有自己完整的结构和功能,多个部件拼装在一起就可以组成一个页面,从组件的实现来看,组件最终是要返回一个jsx对象,不过它和jsx对象的区别是:它是在jsx对象的基础上,还带有自己的方法和属性,能够完成它自己的交互功能.组件有两种定义方式:一种是函数式定义,一种式类定义.
1、函数式定义组件
通过函数来定义一个组件,组件名称首字母要大写,函数接收一个参数props,返回一个jsx对象,其中,name属性式在渲染组件时,通过定义属性传入进来的.
function Welcome(props){
return <h1>Hello,{props.name}</h1>;
}
2、类方式定义组件
上面的组件可以通过下面ES6的类的方式定义,定义的类都要继承于React对象中的Component类,这个定义的组件和上面的功能是等效的.
// 通过类的方式定义组件
class Welcome extends React.Component{
render(){
return(
<h1>Hello,{ this.props.name }</h1>
);
}
}
3、组件渲染
组件渲染和jsx对象一样,我们可以通过React DOM.render()方法来渲染子组件.
function Welcome(props){
return(
<h1>Hello,{ this.props.name }</h1>
);
}
const element = <Welcome name = "Sara" />
ReactDOM.render(element,document.getElementById('root'));
四 、绑定事件
React绑定事件和JavaScript中的行间事件类似,事件绑定是写在标签中的,但是,React事件是在原生事件的基础上做了封装,它的事件使用驼峰命名,而不是全部大小写,事件需要传递一个函数作为事件处理程序,我们通过类定义组件,将这个函数作为方法定义在组件中.
定义一个能弹出的名称的组件:
class HelloTom extends React.Component {
//定义click事件的处理方法
fnHello(){
alert('Hello,Tom!');
}
render(){
return (
<input type="button" value="打招呼" onClick={this.fnHello} />
)
}
}
class HelloName extends React.Component {
//定义click事件的处理方法
fnHello(){
alert('Hello,'+this.props.name);
}
render(){
return (
// 在事件调用方法时,如果方法里面使用了this,在方法中需要绑定this
<input type="button" value="打招呼" onClick={this.fnHello.bind(this)} />
)
}
}
ReactDOM.render(<HelloName name="Jack" />,document.getElementById('root'));
五、状态
组件如果需要定义默认的属性?而且这个默认的属性还是可变的,这个就是组件的状态属性了,状态属性默认名字为state,这个属性需要在组件定义时初始化,所以我们需要使用类的构造函数来对这个属性进行初始化.
class Increase extends React.Component {
constructor(props){
super(props);
this.state = {iNum:10}
};
//state 注意点:
// 1、不能直接修改state的值,应该用setState代替
// 下面的写法是不会更新组件的,是错误的,
// this.state.iNum = 11;
// 应该写成setState的形式:
// this.setState(iNum:11);
//2、state 的值可能是异步的,如果需要在state的值的基础之上修改得到的值,可以使用函数的形式,
// 函数的参数中传递的第一个参数是state上的一个状态,我们可以在这个值的基础上修改,下面的preState代表state上的一个状态:
// this.setState(preState =>({
// iNum:prevState.iNum+1
// }));
// 要通过setState方法来改变state里面的值
// setState里面可以传一个对象,也可以传一个函数,函数需要返回一个对象
fnAdd(){
/*
this.setState({
iNum:11
})
*/
// prevState 指的是state最新的值
/*
this.setState(function(prevState){
return { iNum:prevState.iNum+1}
})
*/
this.setState(prevState=>
({ iNum:prevState.iNum+1})
)
}
render(){
return (
<div>
<p>{this.state.iNum}</p>
<input type="button" value="递增" onClick={this.fnAdd.bind(this)} />
</div>
);
}
}
ReactDOM.render(<Increase />,document.getElementById('root'));