react-02-基础和组件
React介绍
React 是一个用于构建用户界面的 JAVASCRIPT 库。
React 主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)。
React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。
搭建React开发环境
安装 create-react-app 命令 (基于 webpack + es6)
npm install -g create-react-app
使用 create-react-app 创建一个名字叫做 my-app 的项目
create-react-app my-app
如果创建项目过程中,提示node版本低,不兼容,那么执行 yarn config set ignore-engines true 解决该问题。进入 my-app 目录
cd my-app/
启动
npm start
# or
yarn start
yarn 的安装方法:npm i -g yarn
yarn config set registry https://registry.npm.taobao.org -g
yarn config set sass_binary_site https://npm.taobao.org/mirrors/node-sass/ -g虚拟DOM与DIFF算法(重点) 虚拟DOM(Virtual dom),也就是我们常说的虚拟节点,它是通过JS的Object对象模拟DOM中的节点,然后再通过特定的render方法将其渲染成真实的DOM的节点。
// 创建虚拟节点
var temp = document.createDocumentFragment();
for( var i=0;
i<100;
i++ ){
var li = document.createElement('li');
// 将li放入虚拟节点中,这一步操作不会产生重绘回流
temp.appendChild(li);
li.innerHTML = i;
}// 真实节点的操作
ul1.appendChild(temp);
为什么要使用虚拟节点? 频繁的操作DOM,会大量的造成页面的重绘和回流,出于性能优化的考虑,我们应该减少重绘和回流的操作。
重绘:例如 div1.style.color='red' 这种代码,只能改变颜色,并不会影响其他元素的布局,这种操作被称为重绘。
回流:例如 div1.style.padding = '20px' 这种代码,会影响到其他元素的布局,这种操作被称为回流。
回流必将引起重绘,而重绘不一定会引起回流。比如:只有颜色改变的时候就只会发生重绘而不会引起回流。对虚拟节点的DOM操作,并不会触发重绘和回流,把处理后的虚拟节点映射到真实DOM上,只触发一次重绘和回流。
DIFF算法 DIFF算法是DOM更新的一种算法,指页面被更新时,程序用哪种策略去做更新DOM。
JSX语法(重点) React 使用 JSX 来替代常规的 JavaScript。
JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。
- JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
- 它是类型安全的,在编译过程中就能发现错误。
- 使用 JSX 编写模板更加简单快速。
- html标签部分允许嵌套,但顶层仅允许有1个标签。(可以用<>>解决多节点问题)
- 可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。
- JSX 中不能使用 if else 语句,但可以使用三元运算。
- React 推荐使用内联样式。
var myStyle = { fontSize: 100, color: '#FF0000'};
ReactDOM.render(
hello world,
document.getElementById('example')
);
注释:需要写在花括号中
ReactDOM.render(
hello world{/*注释...*/},
document.getElementById('example')
);
数组:JSX 允许在模板中插入数组,数组会自动展开所有成员
var arr = [ 你好, react,];
ReactDOM.render(
{arr},
document.getElementById('example')
);
Fragments
class Columns extends Component {
render(){
return <>
Hello
World
>;
}
}class App extends Component {
render(){
return (
react
);
}
}
无状态组件(影子组件) 优势是创建组件所消耗的资源最少,通常只用于渲染一些普通的html内容。
function Comp1(props){
return
}
有属性,但没有状态,也没有thisClass类组件(重点) 创建及使用组件
class App extends React.Component {
render() {
return Hello World!;
}
}
ReactDOM.render(
,
document.getElementById('example')
);
State状态(重点) React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = { date: new Date() };
}
render() {
return (现在是 { this.state.date.toLocaleTimeString() });
}
// 在组件输出到 DOM 后,会执行 componentDidMount() 钩子。
componentDidMount() {
this.timerID = setInterval(
()=>this.tick(), 1000
);
}
// 组件被从 DOM 中移除,React 会调用 componentWillUnmount()钩子。
componentWillUnmount() {
clearInterval( this.timerID );
}
tick() {
// 设置状态,只要state发生变化,render就会自动重新渲染。
this.setState({ date: new Date() });
}
}
ReactDOM.render( , document.getElementById('example') );
条件渲染(重点) 可以根据应用的状态变化只渲染其中的一部分。
class User extends React.Component {
render() {
var isLogin = this.props.isLogin;
if (isLogin) {
return ;
}else{
return ;
}
}
}
ReactDOM.render( , document.getElementById('root'));
列表循环(重点) 列表和渲染:
render(){
var lis = [a , b ];
return ({lis}
);
}
上面的代码,是能够在ul中显示两个li的,但是console中会报错。“每一项都要有key”
解决方案:
var lis = ["a", "b", "c"].map((val, ind)=>{val} )
Keys 可以在 DOM 中的某些元素被增加或删除的时候帮助 React 识别哪些元素发生了变化。
因此你应当给数组中的每一个元素赋予一个确定的标识。
- key在兄弟元素中必须唯一,但并非全局唯一,即在不同组件中,key可以相同。
- key 会作为给 React 的提示,但不会传递给你的组件。如果您的组件中需要使用和 key 相同的值,请将其作为属性传递
class Welcome extends React.Component {
render() {
return (子组件);
}
}
export default Welcome;
父组件使用
import Welcome from './Welcome.js'
class App extends React.Component {
render() {
return (
父组件
);
}
}
Props属性(重点) 参数 props
class Welcome extends React.Component {
render() {
return Hello World;
}
}
ReactDOM.render(
,
document.getElementById('example')
);
默认属性 defaultProps
class Welcome extends React.Component {
render() {
return {this.props.name};
}
}
Welcome.defaultProps = {
name: '默认值'
};
ReactDOM.render(
,
div
);
绑定事件(重点) 绑定事件时,onClick的C必须大写。
class Welcome extends React.Component {
sum(a, b){
alert('sum:'+(a+b));
}
render() {
return ();
}
}
ReactDOM.render( , div );
注意 sum 函数触发时的 this 指向
class Welcome extends React.Component {
sum(a, b){
alert('sum:'+(a+b));
}
render(){
return ();
}
}
ReactDOM.render( , div );
React.createClass 创建组件
const Comp2 =React.createClass({
mixins: [MixinA],
render(){
return ES5组件的创建方法,已经被废除了,使用会报错。
}
})
受控组件与非受控组件 受控组件说的是该表单元素的值与react的模型层已经绑定在一起了。
class App extends React.Component{
constructor(){
super();
this.state = {
val : 'hello'
}
}
fn(e){
var newVal = e.target.value;
this.setState({
val: newVal
})
}
fn2(){
this.setState({
val: 'hahaha'
})
}
render(){
return ({this.fn(e)}} />
{this.state.val}
);
}
}
如果有 value ,就必须写 onChange非受控组件说的是视图层与模型层没有关联
class App extends React.Component{
constructor(){
super();
this.state = {
val : 'hello'
}
}
fn(){
alert( this.refs.abc.value )
}
render(){
return (
{this.state.val}
);
}
}
Ref 对元素或子组件进行标记 【react-02-基础和组件】ref 可以对元素或组件进行标记。
class Comp2 extends React.Component{
constructor(){
super();
this.state = {
b: 1
}
}
render(){
return abc-{this.props.a}-{this.state.b}
}
}class App extends React.Component{
constructor(){
super();
this.state = {
a : 0
}
}
fn(){
this.setState(state=>({
a : state.a+1
}))
this.refs.abc.state.b = 3;
}
render(){
return (
);
}
}
推荐阅读
- 急于表达——往往欲速则不达
- 第三节|第三节 快乐和幸福(12)
- 20170612时间和注意力开销记录
- 2.6|2.6 Photoshop操作步骤的撤消和重做 [Ps教程]
- 对称加密和非对称加密的区别
- 眼光要放高远
- 樱花雨
- 前任
- 2020-04-07vue中Axios的封装和API接口的管理
- 烦恼和幸福