初学react入门知识整理

初学react总结:
react的最大优点:
1、组件化
类似于web component的组件封装,面向未来。
可复用,可组合的组件框架
2、虚拟dom(virtual dom)
虚拟dom与直接innerhtml的比较:
innerHTML: render html string + 重新创建所有 DOM 元素
Virtual DOM: render Virtual DOM + diff + 必要的 DOM 更新
简单通俗来讲:在我们数据有变动时,不直接全部重新渲染dom结构,而是先在
虚拟dom进行修改,在让虚拟dom与真实dom进行比较,只将有数据改动的dom进行
修改。
3、JSX语法
JSX 是 JavaScript 语言的一种语法扩展,遇到html标签,按照html规则进行
解析;遇到代码块,就按照javasript规则进行解析。



react的学习目录
一、安装
二、HTML如何引入react
三、ReactDOM.render()语法
四、JSX语法
五、组件(component)
1、render方法
1、props
2、proptypes
3、state/setState
六、虚拟DOM(Virtual DOM)
七、表单
八、组件的生命周期
九、如何实现ajax请求获取数据来源



react的学习内容
一、安装
react.js全家桶概念:
1⃣️主体:开发、生产阶段都需要一堆工具和库辅助,编译需要借助babel;
2⃣️redux:--??(待完善)
3⃣️react-router:使用React Router路由控制跳转 (待完善)

安装步骤:
安装node=》
npm install -g create-react-app=》
create-react-app hello-react=》
cd hello-react
npm start=》

终端会提示成功!

二、HTML如何引入react

react 是一定要引入三个js文件:

<head>
<script src="./react.js"></script>
<script src="./react-dom.js"></script>
<script src="./browser.min.js"></script>
</head>
react.js:这个是react的技术主体,是核心库
react-dom.js:提供与DOM相关的功能,其react-dom的核心功能就是把这些虚拟Dom渲染到文档中变成实际dom
browser.min.js:browser.js在浏览器端转换jsx文件
由于browser.min.js文件太大,可以用CDN链接加载 https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js


三、ReactDOM.render()语法
ReactDOM.render()是将我们用的模版转为HTML语言,并插入到指定的dom节点

趣味理解-例如:
ReactDOM.render(
模板(什么东西)
dom节点(要到哪里去)
);
实例:
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
四、JSX语法
什么是JSX?是增强型的js语法-html代码直接放js里。用babel专门编译JSX

注意事项:
1⃣️有且仅有一个父元素

例如:

var names = ['Alice', 'Emily', 'Kate'];

ReactDOM.render(
<div>
{
names.map(function (name) {
return <div>Hello, {name}!</div>
})
}
</div>,
document.getElementById('example')
);


/**在react中用map可以进行遍历*/



五、组件(component)
什么是组件?组件可以使我们项目中将UI划分为一个一个独立的,并且可复用的小部件,
并且可以对每一个部件进行单独的设计。

1⃣️生成组件类:React.createClass 方法就用于生成一个组件类
例如:var HelloMessage = React.createClass({});

2⃣️输出组件:每一个组件类都必须要有自己的render方法
例如:render: function() {
return (jsx表达式);
}

3⃣️组件使用:模板中直接作为标签名(标签必须闭合,自闭合和配套闭合都可以)使用,自定义标签必须大写


5.1、render方法
输出组件:每一个组件类都必须要有自己的render方法

例如:

render: function() {

return (jsx表达式)
}

或:

render () {
const 定义常量
return (jsx表达式)
}

简而言之,在render{}内可以放入任何的javascript的代码,包括变量、表达式计算、函数执行等等。
render会把这些代码返回的内容如实的渲染到页面上,非常的灵活。

render中返回三目运算符用法如下:

render () {
const isRedColor = true
return (
<div>
<h1>
这个颜色
{isRedColor
? <strong> is red</strong>
: <span> is not red</span>
}
</h1>
</div>
)
}


5.2、props
我理解成,props是组件之间传递数据的媒介。
组件从概念上看就是一个函数,可以接受一个参数作为输入值,这个参数就是props,
所以可以把props理解为从外部传入组件内部的数据。
由于React是单向数据流,所以props基本上也就是从服父级组件向子组件传递的数据。

例如:

var HelloMessage = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage name="Danile" />,
document.getElementById('example')
)

若想设置默认的props的值,可以用getDefaultProps()

例如:

getDefaultProps: function() {
return {
name: 'Runoob'
};
},

注意 1⃣️:this.props 对象的属性与组件的属性一一对应,但是有一个例外,
就是 this.props.children 属性。它表示组件的所有子节点。

例如:

var NotesList = React.createClass({
render: function() {
return (
<ol>
{
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>;
})
}
</ol>
);
}
});

ReactDOM.render(
<NotesList>
<span>hello</span>
<span>world</span>
</NotesList>,
document.body
);
输出结果:
1.hello
2.world


注意 2⃣️:class 属性需要写成 className ,for 属性需要写成 htmlFor ,
这是因为 class 和 for 是 JavaScript 的保留字


5.3、proptypes
proptypes是什么?Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,
React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。

例如:

var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,
},

render: function() {
return <h1> {this.props.title} </h1>;
}
});
代码含义:有一个MyTitle的组件,在MyTitle这个组件上有一个title属性。propTypes告诉react,
这个title属性是必须存在的,并且必须是string类型。

若现在,我们给MyTitle的这个组件中的title设置了数值型或者null;

var data = 123;

ReactDOM.render(
<MyTitle title={data} />,
document.body
);

控制台显示:Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.
意思是:告知title这个属性是数值型不通过验证。

想要了解更多propType验证器:http://www.css88.com/react/docs/typechecking-with-proptypes.html

5.4、state/setState
什么是state?组件免不了要与用户互动,就是将组件看成是一个状态机,一开始有一个初始状态,
然后用户互动,导致状态变化,从而触发重新渲染 UI。

由刚才5.2介绍,若想设置默认的props的值,可以用getDefaultProps()。
同理,若想设置一个初始的状态,我们可以用getInitialState。

1⃣️state和props的区别:
一个组件的显示形态可以由数据状态和外部参数所决定,外部参数也就是props,而数据状态就是state。

2⃣️state和setState的区别:
state不同于props的一点是,state是可以被改变的。不过,不可以直接通过this.state=的方式来修改,
而需要通过this.setState()方法来修改state。

用法例如:

var LikeButton = React.createClass({
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? 'like' : 'haven\'t liked';
return (
<p onClick={this.handleClick}>
You {text} this. Click to toggle.
</p>
);
}
});

ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
代码含义:有LikeButton这个组件,getInitialState方法用于定义初始状态,
此处定义了一个初始的方法{liked: false};这个方法也就是一个对象,这个对象
可以通过this.state去被读取。
handleClick()此处就是用户交互行为,数据会进行变化,所以this.setState 方法就修改状态值,
每次修改以后,自动调用 this.render 方法,再次渲染组件。


六、虚拟DOM(Virtual DOM)
什么是虚拟DOM?
React中,先将真实的DOM抽象成一个JavaScript对象,也就是虚拟DOM。

React中虚拟DOM原理
在React中,也有一个render函数来将虚拟DOM树,并且,React中有state转移的过程,所以每次state有变化之后,
就会触发render函数,重新构造一个虚拟DOM树。对比新旧虚拟DOM树的差别,记录下差异,然后只针对差异部分对应的真实DOM进行操作。 

如何进行新旧虚拟DOM树的对比呢? 
这里采用的是Diff算法。Diff算法比较复杂,主要的思路是这样的。 
首先,每一次生成的虚拟DOM树上的各个节点都对应唯一的一个id,当第二次生成了新的DOM树时,对原来树上的每一个节点对比新树上对应节点,
如果不同,就记录下来这个差异。同时,差异也分为很多种:
替换节点;
修改属性;
对文本内容修改
移动、删除、增加节点; 

想详细了解虚拟dom: https://www.zhihu.com/question/29504639


七、表单
此处引入两个概念:受控组件和非受控组件
受控组件:
< input > < select > 都要绑定一个change事件;每当表单的状态发生变化,都会被写入组件的state中,这种组件在React中被称为受控组件;
在受控组件中,组件渲染出的状态与它的value或者checked prop向对应.react通过这种方式消除了组件的局部状态,是的应用的整个状态可控.
react官方同样推荐使用受控表单组件,总结下React受控组件更新state的流程:

1.可以通过初始state中设置表单的默认值;
2.每当表单的值发生变化时,调用onChange事件处理器;
3.事件处理器通过合成事件对象e拿到改变后的状态,并更新应用的state.
4.setState触发视图的重新渲染,完成表单组件值得更新

例如:

<input
type="text"
value={this.state.value}
onChange={(e) => {
this.setState({
value: e.target.value.toUpperCase(),
});
}}
/>

非受控组件:
1.如果一个表单组件没有value props(单选按钮和复选按钮对应的是 checked props)时,就可以称为非受控组件;
2.使用defaultValue和defaultChecked来表示组件的默认状态;
3.通过 defaultValue和defaultChecked来设置组件的默认值,它仅会被渲染一次,在后续的渲染时并不起作用

介绍一下表单中的ref:
ref:
用于获取真实的DOM节点。获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。
为了做到这一点,文本输入框必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点。

八、组件的生命周期

1、生命周期的三个状态
Mounting: 已插入真实 DOM
Updating: 正在被重新渲染
Unmounting: 已移出真实 DOM

2、React为每个状态提供两种处理函数,will(进入状态前调用)/did(进入状态后调用),共5个处理函数
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()

3、React 还提供两种特殊状态的处理函数。
componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用


周期流程状态:
getinitialstate() ==》 componentWillMount() ==》 Mounting render() ==》 componentDidMount()

state改变 ==》 shouldComponentUpdate()==》true ==》 componentWillUpdate() ==》 Update render() ==》 componentDidUpdate()
                                || 
                                ||指向上
父组件改子组件 componentWillReceiveProps


九、如何实现ajax请求获取数据来源
组件的数据来源,通常是通过 Ajax 请求从服务器获取,可以使用 componentDidMount 方法设置 Ajax 请求,
等到请求成功,再用 this.setState 方法重新渲染 UI。

当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求。

例如:

var UserGist = React.createClass({
getInitialState: function() {
return {
username: '',
lastGistUrl: ''
};
},

componentDidMount: function() {
this.serverRequest = $.get(this.props.source, function (result) {
var lastGist = result[0];
this.setState({
username: lastGist.owner.login,
lastGistUrl: lastGist.html_url
});
}.bind(this));
},

componentWillUnmount: function() {
this.serverRequest.abort();
},

render: function() {
return (
<div>
{this.state.username} 用户最新的 Gist 共享地址:
<a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a>
</div>
);
}
});

ReactDOM.render(
<UserGist source="https://api.github.com/users/octocat/gists" />,
mountNode
);

具体代码和运行效果可以看:http://www.runoob.com/react/react-ajax.html


猜你喜欢

转载自blog.csdn.net/shirleyqdd/article/details/80341716