Node安装
1:
......
JSX语法篇
在React的语法中,可以嵌入javascript表达式,方法是将其包装在花括号之内。
举个栗子
{ 2+2 } //输出为4
const user={
name:'奥特曼'
}
const element=(<h1>大家好,我是{user.name},我今年{100+8}岁了</h1>)
{ user.name } //奥特曼
//然后将其添加到我们的reactDom中
reactDom.render({
element,
document.getElementById('root') //暂时不用管这句
})
//也可以作为某个标签的属性
const Imgurl={
url:'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1494412107074&di=ebe4599822bb32b660014cdc6dd26862&imgtype=0&src=http%3A%2F%2Fimg27.51tietu.net%2Fpic%2F2017-011500%2F20170115001256mo4qcbhixee164299.jpg' //神秘图片(/坏笑)
}
const el=(
<img src={}> </img>
)
//然后将其添加到我们的reactDom中
reactDom.render({
el,
document.getElementById('root') //暂时不用管这句
})
//元素标签必须只能有一个标签或者全部在一个DIV中,直接上代码
const element=(//这是对的
<div>我只有一个标签</div>
)
const element=( //这是对的
<div>
<p>我是嵌套的</p>
<p>我是嵌套的</p>
<p>我是嵌套的</p>
</div>
)
const element=( //这样会报错
<div></div>
<p>我是嵌套的</p>
)
JSX表示元素
//jsx表示元素有两种写法,这是第一种也是推荐的一种
const element=(
<h1 className='xpc'>
类名是我名字的缩写 (╯▽╰)
</h1>
)
//这是第二种
const elemen=React.createElement(
'h1', //这里表示元素名
{className:'xpc'},//这里表示元素的属性
'类名是我名字的缩写 (╯▽╰)' //这里表示元素的内容
)
//至于为什么推荐第二种也是一目了然了,第一种简单,下面这些内容摘自官方文档,可看可不看
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world'
}
}
//这些对象被称为“React元素”。你可以将它们看成是你想要在屏幕上看到的内容。React读取这些对象,并使用它们构造DOM并保持最新。
//建议在你的编辑器上面安装Babel语法插件,本人用的VsCode非常和谐
这时候咱们应该做一个简单的小案例了,显示美女图片,直接上代码
const user ={
name:'xpc',
lastname:'韦森莫.拉默衰.率的伊比',
url:'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1494412107'
+'074&di=ebe4599822bb32b660014cdc6dd26862&imgtype=0&src=http%3A%2F%2Fimg27.51tietu.net%2Fpic%2F2017-011500%2F20170115001256mo4qcbhixee164299.jpg'
}
const time=()=>{
const element=(
<div>
<div>hhh 时间为</div>
<h2>It is {new Date().toLocaleTimeString() }</h2>
<img src={user.url} alt=""/>
</div>
)
ReactDOM.render(
element,
document.getElementById('root')
);
}
setInterval(time,1000)
老子最烦的原理性的东西来了,虽然很强大,但是老子不喜欢
简单的说就是归react管理的DOM都放在一个DIV中,这个DIV称之为根节点
document.getElementById('root')
//拥有这个rootID的元素就是根节点,和ng的ng-app一样,
//咱们写的DOM元素等等都在这个DIV中渲染
//假设咱们的DOM改变了内容,react会把这个更新了的DOM和原来的DOM进行比较,如果两者有不同的地方则只更新不同的地方
//想继续了解的话右转百度 ReactDiff算法
组件
组件简单来说就是某个功能或者UI,一个按钮可以称之为一个组件,咱们的一整个网页也可以称之为一个组件,一个大组件由很多小组件构成,而小组件由更多的小小组件构成
摘自官方文档
功能组件
定义组件最简单的方法就是编写一个javascript函数
function Welcome ( props){
return <h1> hello,{props.name} </h1>
//这个函数是一个有效的React组件,因为他接受一个"props"对象参数并与数据返回一个React对象
//我们将这种组件称之为功能组件
}
让我们实用ES6类的方式来定义组件
class Welcome extends React.component {
render (){
return <h1> Hello,{this.props.name}<h1>
}
}
//怎么用?
const a=< Welcome name='xpc' />
然后将a放到咱们的render中
渲染组件
//这是我们遇到的代表Dom标签的React元素
const element=<div />
//我们也可以这样表示定义的组件
const = <Welcome name='Sara'>
//当react看到定义的组件时,它将JSX属性作为单个对象传递给该组件,我们称这个对象为"道具"
警告 : 始终实用大写字母启动组件,意思就是组件不管咋样开头第一个字母必须是大写,不信你试试。
咱们的组件调用时,后面的 斜杠必须加上,不信你试试。
组成部分
组件可以在输出中引用其他组件。这使我们可以对任何级别的细节使用相同的组件抽象。
一个按钮,轮播图,导航栏,都可以称之为组件。
让我们写一个按钮,点击弹出登陆成功,上代码
var btn=()=>{
alert('登陆成功')
}
class Login extends React.Component{
render (){
return <input type='button' value={this.props.name} onClick={this.props.ock} className='xpc'/>
}
}
const el=<Login name='点击我' ock={btn}/>
ReactDOM.render(
el,
document.getElementById('root')
);
// 让我们看一下这段代码发生了什么
// 1:首先咱们定义了一个类,这个类继承自React中的Component这个东西
// 2:然后这个类中有一个render方法,这个方法返回了一个DOM对象
// 3:这时候咱们的react看到咱们定义了一个组件,用咱们的JSX语法将咱们的道具传递到咱们的类
// 4:咱们的react通过JSX语法看到了有一个click事件,这个事件调用了btn函数,再次寻找到btn这个函数
// 5:最后咱们el就是一个完整的DOM对象,有类名,有点击事件等等...
// 6:进入页面点击按钮,显示登陆成功
// 关于这部分我不想打太多字,谁叫我懒呢。不过这一部分个人感觉又是挺重要的,所以还是写了这几步。
// 整个过程类似咱们的构造函数和继承
篇幅太多,下次再说
提取组件
不要被提取组件这四个字困扰,其实就是这么说吧。
每个组件应该易于维护,应该是一个大的组件中包含更多的小组件,这样维护的话会更加方便。
直接上代码
const Ass=(props)=>{
return (
<div>
<div className={props.class}>
<img src={props.one.url} />
</div>
<div className={props.class}>
<h1>{props.h1}</h1>
</div>
<div className={props.class}>
<input type={props.type} value={props.val}/>
</div>
</div>
)
}
把这个组件看成页面中的一个组件的话,三个DIV分别是三个小组件,是一个完整的组件。
这样的话不容易维护,不容易开发,代码可读性下降,代码重用性降低
算 了,还是直接上代码吧
//此时我们应该做的是将里面小组件提取出来,这样的好处是显而易见的,可读性/可维护性。
var dt={
one:{
url:'https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1494474659&di=9160621335f3050d9040f74b269eba77&src=http://img27.51tietu.net/pic/2017-011500/20170115001256mo4qcbhixee164299.jpg'
},
two:{
h1:'辛啊啊啊啊啊'
},
there:{
ty:'button',
val:'哈哈哈哈哈哈哈'
}
}
class Ass extends React.Component{
render (){
return <div>
<div className='xpc1'>
<One user={this.props.props.one}/>
</div>
<div className='xpc1'>
<Two user={this.props.props.two}/>
</div>
<div className='xpc1'>
<There user={this.props.props.there}/>
</div>
</div>
}
}
//第一个小组件
class One extends React.Component{
render (){
return <img src={this.props.user.url}/>
}
}
//第二个小组件
class Two extends React.Component{
render (){
console.log(this)
return <h1>{this.props.user.h1}</h1>
}
}
//第三个小组件
class There extends React.Component{
render (){
return <input type={this.props.user.ty} value={this.props.user.val} />
}
}
const Asss=<Ass props={dt}/>;
ReactDOM.render(
Asss,
document.getElementById('root')
);
//这里涉及的组件传值不要关注,关注的是组件的提取
这里咱们看一下组件之间的道具
https://facebook.github.io/react/docs/components-and-props.html
这个网址最后一块是组件之间的道具
状态和生命周期
到了现在,咱们只会一种更新DOM的方式,就是用非常傻叉的定时器,这次咱们学点不那么傻叉的。
首先,咱们用一种傻叉1.0的方式写一个时钟,因为不想写,所以没有那么好看。
class Clock extends React.Component {
render (){
console.log(this.props.date)
return <div>
<img src={dt.one.url}/>
<h1>{this.props.date.toLocaleTimeString()}</h1>
</div>
}
}
var tick =()=>{
ReactDOM.render(
<Clock date={new Date()} />,
document.getElementById('root')
);
}
setInterval(tick,1000)
//略显傻叉,咱们在换一种方式
//但是建议使用类的方式写,类其实就是构造函数的另一种写法
这时候使用我们的类的方式改造一下我们的代码
class Clock extends React.Component {
constructor(props){
super(props)
this.state={date:new Date()}
}
render (){
return <div>
<img src={dt.one.url}/>
<h1>{this.state.date.toLocaleTimeString()}</h1>
</div>
}
}
var tick =()=>{
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
}
setInterval(tick,1000)
//下面我们看一下将=生命周期方法添加到类中
将 生命周期方法添加到类中
在许多具有组件的程序中,释放组件在销毁时所占用的资源非常重要。
第一次渲染DOM时,我们需要时间器,这在react中称之为"挂载",
我们想要清楚这个定时器,只要将这个类删除就好,这在react中称之为卸载。
当组件挂在和卸载时,我们可以在组件上声明特殊的方法来运行这些代码。
class Clock extends React.Component {
constructor(props){
super(props)
this.state={date:new Date()}
}
componentDidMount(){
this.itmerID=setInterval(()=>this.tick(),1000)
}
componentWillUnmount(){
clearInterval(this.itmerID)
}
tick(){
this.setState({
date:new Date()
})
}
render (){
return (
<div>
<img src={dt.one.url}/>
<h1>{this.state.date.toLocaleTimeString()}</h1>
</div>
)
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
//这是咱们修改之后的代码
//关于这两个生命周期的方法
// 1: componentDidMount 2:componentWillUnmount
// 百度!
算了我还是解释解释吧
componentDidMount : 意思就是当咱们的DOM元素渲染出来之后开始执这个函数里面的代码,类似咱们Vue中的Created钩子函数.也可以通过this.getDOMNode()访问到真实的DOM元素,此时可以使用其他的类库来操作这个DOM;
componentWillUnmount : 意思是当咱们挂载了一个组件之后,当咱们不需要这个组件的时候咱们需要将这个组件卸载,类似于浮动与清除浮动的关系,是关系!不是作用!
其他的明天再说!