react教程 零基础8天落地 上项目开发

前言:如果‬‬只愿意做松轻‬‬的事,人生就会困难重重;而果如‬‬你愿意做困难的事,那么人生就会变得轻松。为什么?

前置技能:

  1.  React 开发前置技能 使用 VS Code 搭建 TypeScript 开发环境_cao919的专栏-CSDN博客
  2. javaScript进阶 ES6 详细全解,解构赋值,Proxy,箭头函数,class类, 模块,export和import,Promise,then 方法,async等等_cao919的专栏-CSDN博客
  3. 前端 webpack 4 打包工具_cao919的专栏-CSDN博客_前端打包工具

------------------

react教程

1. 背景介绍

React 是什么?

React 起源于Facebook的内部项目。2013年开源供给大家使用是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。

React的声明式特点减少了操作DOM的性能损耗,同时组件化开发使得大量的组件得以复用。内部实现的虚拟DOM和DOM diff算法使DOM的操作变得高效。

React 特点

  • 1.声明式设计 −React采用声明范式,可以轻松描述应用。

  • 2.高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。

  • 3.灵活 −React可以与已知的库或框架很好地配合。

  • 4.JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。

  • 5.组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。

  • 6.单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,也维护的数据安全性

虚拟DOM

虚拟DOM(Virtual DOM)的机制:在浏览器端用Javascript实现了一套DOM API。React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新。而且React能够批处理虚拟DOM的刷新,例如你连续的先将节点内容从A变成B,然后又从B变成A,React会认为UI不发生任何变化。

CDN引入React

 <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
 <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>

使用CDN方式引入的时候,script片段代码需要申明type为text/babel

JSX语法

直接写在 JavaScript 语言之中的HTML 语言就是JSX。JSX,是一种 JavaScript 的语法扩展,它允许 HTML 与 JavaScript 的混写。JSX是facebook为React框架开发的一套语法糖

const dom = <h1>Hello, world!</h1>;

你可以任意地在 JSX 当中使用 JavaScript 表达式,在 JSX 当中的表达式要包含在大括号里。

const name = 'Tina';
const element = (
  <div>
     Hello, {name}! 
  </div>
);

JS语法

react提供了一个createElement方法创建虚拟DOM,方法接收3个参数,第一个参数是标签名,第二是标签属性,第三个是标签内容。

 const dom =  React.createElement('h1','','hello,word!')

2.项目搭建

使用脚手架创建项目

npx是webpack的运行工具

npm install -g create-react-app
create-react-app my-app
cd my-app
npm start

添加路由库 react-router-dom

npm i react-router-dom

3.组件

一个应用/版块/页面中用于实现某个局部的功能(包括html, js, css等)把这些局部功能组装到一起,就形成了组件

在react里,组件的最小颗粒度是一个标签元素

1.无状态组卷 2.有状态组件

创建组件

  • 用函数定义组件

    function HelloMessage(props) {
        return <h1>Hello World!</h1>;
    } 
  • 使用Class定义组件

    class HelloMessage extends React.Component {
      render() {
        return <h1>Hello World!</h1>;
      }
    }

4.State状态

React 把组件看成是一个状态机。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。

React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。

在React中,我们可以在组件(Class定义的组件)里添加一个类构造函数来初始化状态 this.state,类组件应始终使用 props 调用基础构造函数。

class HelloMessage extends React.Component {
   constructor(props) {
    super(props);
    this.state = {name: 'World'};
  }
  render() {
    return <h1>Hello {this.state.name}!</h1>;
  }
}

更改组件的name属性,即可更改页面渲染结果

class HelloMessage extends React.Component {
   constructor(props) {
    super(props);
    this.state = {name: 'World'};
  }
  nameChange(){
  	 this.setState({
         name:'Tina'
     })
  }
  render() {
    return <div>
        	<h1>Hello {this.state.name}!</h1>
      		<button onClick={()=>{this.nameChange()}}>变身</button>
        </div>;
  }
}

5.事件绑定

React 元素的事件处理和 DOM 元素类似。但是有一点语法上的不同:

  • React 事件绑定属性的命名采用驼峰式写法,而不是小写。

  • 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数

    <button onClick={()=>{this.tick()}}>
      增加
    </button>

    在通过Class创建的组件内,想要使用this调用函数,可以在构造函数内bind this对象为当前this,也可以在绑定处使用this调用

    class App extends React.Component{
                constructor(props){
                    super(props)
                    this.state = {
                        age:this.props.age
                    }
                    this.ageChange = this.ageChange.bind(this);
                }
               ageChange(){
                    this.setState({
                        age:this.state.age+1
                    })
                }
    
                render(){
                    return <div>
                       	<span>我今年{this.state.age}岁了</span>
                        <button onClick={()=>{this.ageChange()}}>过年了</button>
                        </div>
                }
            }

6.组件props

组件state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。state是组件内部自己定义的,而props是父组件调用时提供的

function HelloMessage(props) {
    return <h1>Hello {props.name}!</h1>;
}
 
const element = <HelloMessage name="Runoob"/>;
 

通过Class创建的组件,使用this调用props,而在使用之前,需要在类构造函数内,使用super(props)注入

class HelloMessage extends React.Component {
	constructor(props){
        super(props)
     }
  render() {
    return <h1>Hello {this.props.name}!</h1>;
  }
}

7.条件渲染

在 React 中,可以创建不同的组件来封装各种你需要的行为。然后还可以根据应用的状态变化只渲染其中的一部分。也可以在React 中的使用 if 或条件运算符来创建表示当前状态的元素,然后让 React 根据它们来更新 UI。

	const NavTitle=(props)=>{
            if(props.type===1){
                return <h1>{props.title}</h1>
            }else if(props.type===2){
                return <h2>{props.title}</h2>
            }
       }

三目运算

const NavTitle=(props)=>{
   return props.type===1?<h1>{props.title}</h1>: <h2>{props.title}</h2>
 }

8. 列表

react中,可以通过数组生成一系列标准结构组件,通过map方法完成列表渲染

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((numbers) =>
  <li>{numbers}</li>
);

生成原理其实是使listItems成为一个数组容器,容器内部则是<li>{numbers}</li>组件,最后react内部可直接展开数组渲染

如果直接将numbers最为组件,则会展开成为内容被渲染

react在列表渲染的时候需要给组件指定一个key作为组件的唯一标识,该属性不会作为组件的props被接收,仅供react内部计算使用

Key 可以在 DOM 中的某些元素被增加或删除的时候帮助 React 识别哪些元素发生了变化。

9、Refs

React 支持一种非常特殊的属性 Ref ,你可以用来绑定到render() 输出的标签上。

这个特殊的属性允许你引用相应的实例。

<input ref="myInput" />
var input = this.refs.myInput;

引用传递 Forwarding Refs

如果需要给组件绑定ref则上面的方式不支持,react提供了forwardRef方法来支持组件的引用,引用测方式是用过forwardRef函数传递ref的引用

const InpuDom= forwardRef((props, ref) => (
    <input type="text" ref={ref} />
));
class ForwardRef extends Component {
    constructor(props) {
        super(props);
        this.ref = createRef();
    }

    componentDidMount() {
        const { current } = this.ref;
        current.focus();
    }

    render() {
        return (
            <div>
                <p>forward ref</p>
                <InpuDom ref={this.ref} />
            </div>
        );
    }
}

10.组件生命周期

生命周期的方法有:

  • componentWillMount --在渲染前调用

  • componentDidMount --在第一次渲染后调用

  • componentWillReceiveProps --在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。

  • shouldComponentUpdate --返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。(可以在你确认不需要更新组件时使用。)

  • componentWillUpdate --在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

  • componentDidUpdate --在组件完成更新后立即调用。在初始化时不会被调用。

  • componentWillUnmount --在组件从 DOM 中移除之前立刻被调用。

11.组件传值

父组件向子组件传值(自定向下)可以直接使用props完成

<List ref={this.ref} {...this.state.list[0]}/>

而子组件向父组件传值是自底向上的,这种操作react内部是不支持直接操作的,我们可以选择使用函数props来完成需求

通过在父组件引入的子组件中传递一个函数并传参,子组件去触发这个函数更改参数完成数据更新

子组件

	const List = React.forwardRef((props,ref)=>{
           const userNameClickFun=(name)=>{
                props.getUserName(name)
            }
            return <div ref={ref} className="list">
                <div onClick={()=>{userNameClickFun(props.name)}} className="left"></div>
                <div className="right">
                    <div className="info">{props.name}</div>
                    <div className="text">{props.text}</div>
                </div>
             </div>
        })

父组件

 getUserNameFun(name){
     console.log(name)
 }
render(){
    return <div className="comment-box">
            {
            this.state.list.map(v=><List getUserName={this.getUserNameFun} key={v.id} {...v}/>)
            }
            <div className="inp">
                <textarea ref="inpDom" onChange={(e)=>{this.getText(e)}}></textarea>
                <div>
                	 <button onClick={()=>{this.subFun()}}>提交评论</button>
                </div> 
            </div>
		</div>
}

12.高阶组件

如果一个函数操作其他函数,将其他函数作为参数或将函数作为返回值,将其称为高阶函数。高阶组件类似于高阶函数,接收 React 组件作为输入,输出一个新的 React 组件。高阶组件让代码更具有复用性、逻辑性与抽象特征。可以对 render 方法作劫持,也可以控制 props 与 state。

简单来说,高阶组件只是一个包装了另外一个 React 组件的 React 组件

		const NavTitle=(props)=>{
           return props.type===1?<h1>{props.title}</h1>: <h2>{props.title}</h2>
        }

        const Nav = (props)=>{
            if(props.type!=1&&props.type!=2){
                return <p>{props.title}</p>
            }else{
                let newPro={
                    ...props,
                    title:'高阶标题'+props.title
                }
                return <NavTitle {...newPro}/>
            }
        }

13.Hook

使用函数声明的组件大多数为无状态组件,展示型组件一般是无状态组件

Hook是供给函数组件进行状态管理的方法,只能在 React 的函数组件中调用 Hook

State Hook

通过useState申明一个值为0的变量,并且同时可以获得一个可以更改当前变量的方法,通过setCount方法修改的count可以同时更新页面。等价Class组件的statesetState

function Example() {
  // 声明一个叫 "count" 的 state 变量
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Effect Hook

useEffect简单理解就是监听函数组件中的数据。是componentDidMountcomponentDidUpdatecomponentWillUnmount 这三个函数的组合

useEffect(() => {
    document.title = `You clicked ${count} times`;
  });
posted @ 2021-10-23 18:13  cao919  阅读(116)  评论(0编辑  收藏  举报