React基础用法

灰太狼 2022-12-17 11:54 274阅读 0赞

React基础

脚手架安装

npm i -g create-react-app //全局安装

安装完成以后,在控制台输入如下命令,验证是否安装成功

create-react-app —version

脚手架创建项目

create-react-app 项目名称

脚手架项目结果

image-20201023084047192
1.public是公开文件夹
2.src目录是开发目录

  • index.js是整个程序的启动目录,也是webpack的入口文件
  • index.css是程序程序的公共CSS文件,如果需要写公共CSS文件最好写在这里
  • App.js是根组件,在React里面,这就是一个根组件,React的组件是以JS文件的形式存在
  • App.css是App.js组件的样式,一般情况下,一个JS文件会对应一个CSS文件
  • serviceWorker.js是在开发React的时候启动的http服务器

分析React脚手架项目的启动

index.js文件

  1. import React from 'react'; //导入React,一定要导,即使你没有用
  2. import ReactDOM from 'react-dom'; //因为主要是操作DOM,所以这个是React操作DOM的
  3. import './index.css'; //导入样式文件
  4. import App from './App'; //导入App.js,它是一个组件
  5. import * as serviceWorker from './serviceWorker'; //启用动开的时候后台服务,开启HMR热模块
  6. //下面的代码就相当于 Vue当中的new Vue({})的代码。创建实例,接管区域,渲染组件
  7. ReactDOM.render(
  8. <React.StrictMode>
  9. <App />
  10. </React.StrictMode>,
  11. document.getElementById('root')
  12. );
  13. serviceWorker.unregister(); //当程序退出的时候,退出后台

React当中的语法使用的是JSX的语法,它不是完全的JS语法

认识JSX语法

它是一种全新的语法,也是比较流行一种语法,它将JS语法与HTML语法来进行混合使用,就是说可以在写JS的时候去插入HTML代码

React的开发完全用ES6及JSX 的语法,JSX本质上面所做的事情还是MVVM 的,只是换了一种方式在操作,它里面也有条件渲染,列表渲染,属性渲染,事件处理,组件化等操作(这些操作都是Vue当中自带的,只是在React里面要自己手写)

创建组件

在React当中一切皆组件,所以我们可以把CSS与好,JS也好都看成是一个组件,在目前创建组件的时候有两种方式,也就是目前React开发的两种方式

  1. 基于class的开发
  2. 基于React Hooks Api的开发(这是目前新堆出来的一种开发方式)

    import React from “react”; //导入React
    class App extends React.Component{
    //在组件的内部,必须有一个方法render,这个方法负责在页面上面渲染数据
    render(){

    1. //render函数return的东西就是页面上面显示的东西
    2. //在return的后面只能有一个根标题,与vue当中的template一样,也只能也有一个根标签
    3. return (
    4. <div>
    5. <h1>这是一个1号标题</h1>
    6. <h1>这是一个2号标题</h1>
    7. </div>
    8. );

    }
    }

    export default App;

注意事项:组件的名称一定是大写开头的

普通数据渲染

React最主要的一点就是与Vue是一样的,都是数据驱动页面,关注数据的变化就可以了,所以在React当中,它的数据应该在哪里呢?怎么渲染呢?

在Vue当中,我们的数据来源于三个地方,第一个是data,第二个是computed,第三个来源于父级props

在React当中,它的数据主要来源于两个地方,第一个是自身的数据state,第二个是父级数据props

  1. render(){
  2. //render函数return的东西就是页面上面显示的东西
  3. //在return的后面只能有一个根标题,与vue当中的template一样,也只能也有一个根标签
  4. return (
  5. <div>
  6. <h1>这是一个1号标题------ { this.state.userName} </h1>
  7. <h1>这是一个2号标题</h1>
  8. </div>
  9. );
  10. }

在JSX语法里面,如果在HTML标签当中要嵌入JS代码 则使用{}包裹就可以了

条件渲染

  1. //在组件的内部,必须有一个方法render,这个方法负责在页面上面渲染数据
  2. render(){
  3. //render函数return的东西就是页面上面显示的东西
  4. //在return的后面只能有一个根标题,与vue当中的template一样,也只能也有一个根标签
  5. return (
  6. <div>
  7. <h1>这是一个1号标题------ { this.state.userName} </h1>
  8. <h1>这是一个2号标题</h1>
  9. <hr />
  10. <p>{ this.state.age>=18?'成年':'未成年'}</p>
  11. <hr />
  12. { this.state.age>=18&&<h2>这是一个非常好看的标签,age大于等于18就显示,否则就隐藏,怎么办?</h2>}
  13. </div>
  14. );
  15. }

React当中的条件渲染使用的是之前ES基础里面的逻辑操作符的特性短路原则来实行的

列表渲染

React当中的列表渲染借助于是数组语法,在数组语法当中,我们有一个map方法

  1. <ul>
  2. { this.state.stus.map((item,index)=>{
  3. return <li key={ index}>{ item}</li>
  4. })}
  5. </ul>

在做列表渲染的时候,与Vue一样,在每个渲染的元素上面要添加一个特殊的属性key,保证它的唯一性

**注意事项:**在React当中会大量使用箭头函数,箭头函数后面是否跟花括号是完不一样的

上面的代码如果不跟花括号,可以写成如下。因为不跟花括号{}则代表后面的东西是返回值

  1. <ul>
  2. { this.state.stus.map((item,index)=>
  3. <li key={ index}>{ item}</li>
  4. )}
  5. </ul>

**扩展:**如果我们现在需要在页面上面渲染10个button应该怎么办呢?

  1. renderButton(){
  2. let arr = [];
  3. for(var i=0;i<10;i++){
  4. arr.push(<button type="button">按钮{ i}</button>)
  5. }
  6. return arr;
  7. }
  8. render(){
  9. return (
  10. <div>
  11. { this.renderButton()}
  12. </div>
  13. );
  14. }

在JSX代码当中可以直接把一部分代码重新封装成方法再进行。同时我们得出一些,列表渲染是需要得到一个数组再渲染

属性渲染

在Vue当中Vue如果要渲染属性需要使用v-bind:属性名来进行绑定,但是在React当中完全没有必要,还是直接使用JSX语法就行了

  1. <button type="button" abc={ userName}> 按钮 </button><a href={ this.state.url1}>百度一下,你就知道</a>

始终记得一点,{}里面的就是JS代码就可以了

样式设置

在React的JSX语法当中,有一点与众不同就是样式的设置,因为在JSX的内部class是一个关键字,所以在设置元素的样式的时候,已经不能使用class来设置,要转而使用另一个关键字className

App.css文件

  1. .box1{
  2. width: 100px;
  3. height: 100px;
  4. border: 2px solid red;

App.js文件

  1. import "./App.css"; //导入CSS文件
  2. <div className="box1">这是一个盒子</div>

重点:在之前的Vue里面,我们的<style scoped></style> 会有一个scoped的属性,这个属性主要用于设置当前Vue文件内部的样式只作用于当前的<template>,那么在React当中应该怎么实现这个功能呢?
上面的我们直接使用<div className="box1">这是一个盒子</div>这是一个最普通的方式,它没有实现CSS的模块化

  1. 先将CSS文件名添加一个.module,如原来的App.css就会变成App.module.css文件
  2. 在App.js当中去导入的时候变成如下代码

import AppStyle from “./App.module.css”;

  1. 在使用的样式的时候应该如下使用

这是另一个盒子

动态样式绑定

  1. constructor(){
  2. super(...arguments);
  3. this.state={
  4. navType:1
  5. }
  6. }
  7. render(){
  8. return (
  9. <div>
  10. <ul className="navType">
  11. <li className={ this.state.navType==0?'selected':null}>正在热映</li>
  12. <li className={ this.state.navType==1?'selected':null}>即将上映</li>
  13. </ul>
  14. </div>
  15. );
  16. }

如果class的样式需要叠加的时候,在React当中会比较麻烦,但仍然有两种写法

1.借用ES6当中的模板字符串去完在

  1. <ul className="navType">
  2. <li className={ `abc ${ this.state.navType===0?'selected':null}`}>正在热映</li>
  3. <li className={ `abc ${ this.state.navType===1?'selected':null}`}>即将上映</li>
  4. </ul>

2.借用数组去完成

  1. <ul className="navType">
  2. <li className={ ["abc",this.state.navType===0?'selected':null].join(' ')}>
  3. 正在热映
  4. </li>
  5. <li className={ ["abc",this.state.navType===1?'selected':null].join(' ')}>
  6. 即将上映
  7. </li>
  8. </ul>

在React当中,React不建议我们去使用style去设置属性,但是并不是不能,如果要用可以按下面的方式来使用

  1. this.state={
  2. styleObj:{
  3. width:"100px",
  4. height:"100px",
  5. border:"1px solid black"
  6. }
  7. }
  8. <div style={ this.state.styleObj}>
  9. 这是一个盒子
  10. </div>

上面就是设置style的过程,我们看起来操作很麻烦,需要先定义一个对象,然后style再去引用这个对象,但是我们平常在开发的时候,可能就直接写成下面的样式了

  1. <div style={ { width:"100px",height:"100px",border:"1px solid red"}}>
  2. 这又是一个盒子
  3. </div>

组件化

之前已经学过了组件的创建,在本个环节,我们主要两个点

  1. 父级组件如何向子级组件传值
  2. 之前在vue当中的<slot>在React是如何实现的

父级组件向子级组件传值
App.js文件

  1. <Home abc={ this.state.userName} userAge={ this.state.userAge}>
  2. </Home>

Home.js文件

  1. <h2>{ this.props.abc}--------{ this.props.userAge}</h2>

React当中的自定义属性是支持驼峰命名的

Vue中Slot的实现方式
在以前的时候Vue可以通过Slot来向子组件的某个地方去插入数据,在React当中也有类似的实现的方式

App.js文件中,我们在<Home>组下面插入了一个东西

  1. <Home abc={ this.state.userName} userAge={ this.state.userAge}>
  2. <button type="button">这是通过Slot进来的</button>
  3. </Home>

Home.js的文件中,怎么接收插入的内容呢

  1. <div>
  2. { this.props.children}
  3. </div>

this.props.children就是插槽的数据

事件及事件处理

在React的JSX的语法当中,它的事件也是支持的,但是它的事件与做了相应的转换过程,如下所在

  1. onclick转变成了onClick
  2. onchange转变成了onChange

以前的事件名是全小写,现在on后面根的事件类型名变成了大写

  1. test(){
  2. console.log(this);
  3. alert("你好啊");
  4. }
  5. <button type="button" onClick={ this.test.bind(this)}>按钮2</button>

所以在上面的的样式绑定里面,我们可以通过事件去改变navType以实现样式的改变

  1. changeNavType(type){
  2. console.log(type);
  3. // 如果要改变state 的状态,要调用setState的方法
  4. this.setState({
  5. navType:type
  6. });
  7. }
  8. <ul className="navType">
  9. <li onClick={ this.changeNavType.bind(this,0)}
  10. className={ ["abc",this.state.navType===0?'selected':null].join(' ')}>
  11. 正在热映
  12. </li>
  13. <li onClick={ this.changeNavType.bind(this,1)}
  14. className={ ["abc",this.state.navType===1?'selected':null].join(' ')}>
  15. 即将上映
  16. </li>
  17. </ul>

React当中的单页面开发

在Vue当中Vue为了实现单页面开发使用的是vue-router来跳转页面,而在React里面,它也有路由,它使用的是下面两个包

  1. react-router
  2. react-router-dom

这两个包的配置与vue-router截然不同

安装路由的包

yarn add react-router react-router-dom —dev

配置路由

路由的配置方式有两种,第一种使用嵌套的方式在组件内部写,如下

App.js文件

  1. import React from 'react';
  2. import './App.css';
  3. import { HashRouter, Route, Switch } from "react-router-dom";
  4. import Home from "./views/Home/Home";
  5. import Detail from "./views/Detail/Detail";
  6. class App extends React.Component {
  7. //当一个路由嵌套另一个路由的时候,一定不能添加exact
  8. render() {
  9. return (
  10. <HashRouter>
  11. <Switch>
  12. <Route path="/Home" component={ Home}></Route>
  13. <Route path="/Detail" component={ Detail} exact></Route>
  14. </Switch>
  15. </HashRouter>
  16. );
  17. }
  18. }
  19. export default App;

Home.js文件

  1. import React from "react";
  2. import HomeStyle from "./Home.module.scss";
  3. import ChooseFood from "../ChooseFood/ChooseFood";
  4. import Order from "../Order/Order";
  5. import { Route } from "react-router-dom";
  6. class Home extends React.Component{
  7. render(){
  8. return(
  9. <div className={ HomeStyle.homePage}>
  10. <div className={ HomeStyle.routerBox}>
  11. <Route path="/Home/ChooseFood" component={ ChooseFood} exact></Route>
  12. <Route path="/Home/Order" component={ Order} exact></Route>
  13. </div>
  14. <ul className={ HomeStyle.tabBar}>
  15. </ul>
  16. </div>
  17. );
  18. }
  19. }
  20. export default Home;

路由在渲染组件的时候,可以使用两种方式

  1. <HashRouter>
  2. <Switch>
  3. <Route path="/Home" component={ Home}></Route>
  4. <Route path="/Detail" exact render={ props => {
  5. return <Detail></Detail>
  6. }}></Route>
  7. </Switch>
  8. </HashRouter>

第一种是直接使用component属性来渲染,第二种则是手动的调用render函数,然后返回一个组件

我们的路由的第二种配置就是使用第二种render函数来的

App.js的配置方法

  1. import React from 'react';
  2. import './App.css';
  3. import { HashRouter, Route, Switch,Redirect } from "react-router-dom";
  4. import Home from "./views/Home/Home";
  5. import ChooseFood from "./views/ChooseFood/ChooseFood";
  6. import Category from "./views/Category/Category";
  7. import Order from "./views/Order/Order";
  8. import MySelf from "./views/MySelf/MySelf";
  9. import Detail from "./views/Detail/Detail";
  10. class App extends React.Component {
  11. //当一个路由嵌套另一个路由的时候,一定不能添加exact
  12. render() {
  13. return (
  14. <HashRouter>
  15. <Switch>
  16. <Redirect path="/" to="/Home/ChooseFood" exact></Redirect>
  17. <Route path="/Home" render={ props => {
  18. return <Home { ...props}>
  19. <Route path="/Home/ChooseFood" component={ ChooseFood} exact></Route>
  20. <Route path="/Home/Order" component={ Order} exact></Route>
  21. <Route path="/Home/Category" component={ Category} exact></Route>
  22. <Route path="/Home/MySelf" component={ MySelf} exact></Route>
  23. </Home>
  24. }}></Route>
  25. <Route path="/Detail" component={ Detail} exact ></Route>
  26. </Switch>
  27. </HashRouter>
  28. );
  29. }
  30. }
  31. export default App;

Home.js页面

  1. <div className={ HomeStyle.homePage}>
  2. <div className={ HomeStyle.routerBox}>
  3. { this.props.children}
  4. </div>
  5. <div className={ HomeStyle.tabBar}>
  6. <NavLink to="/Home/ChooseFood" activeClassName={ HomeStyle.active}>
  7. <span className="iconfont iconcanju" style={ { fontSize:"22px"}}></span>
  8. 点餐
  9. </NavLink>
  10. <NavLink to="/Home/Order" activeClassName={ HomeStyle.active}>
  11. <span className="iconfont icondingdan" style={ { fontSize:"22px"}}></span>
  12. 订单
  13. </NavLink>
  14. <NavLink to="/Home/Category" activeClassName={ HomeStyle.active}>
  15. <span className="iconfont iconfenlei" style={ { fontSize:"22px"}}></span>
  16. 分类
  17. </NavLink>
  18. <NavLink to="/Home/MySelf" activeClassName={ HomeStyle.active}>
  19. <span className="iconfont iconyonghuming" style={ { fontSize:"22px"}}></span>
  20. 我的
  21. </NavLink>
  22. </div>
  23. </div>

如果需要通过JS的方法去跳转面页面,则可以找this.props.history这个对象,它相当于Vue里面的this.$router

发表评论

表情:
评论列表 (有 0 条评论,274人围观)

还没有评论,来说两句吧...

相关阅读

    相关 React基础

    React基础 脚手架安装 > npm i -g create-react-app //全局安装 安装完成以后,在控制台输入如下命令,验证是否安装成功 > cr