项目地址

  • 教程作者:SGG
  • 教程地址:
https://www.bilibili.com/video/BV1wy4y1D7JT/?spm_id_from=333.999.0.0&vd_source=791e6deaa9c8a56b1f845a0bc1431b71
  • 代码仓库地址:
  • 所用到的框架和插件:
req

一、创建第一个react项目

  1. 执行创建命令,创建名为react-basic的项目文件
npx create-react-app react-basic
  1. 进入到项目的根目录,开启react服务
npm start

在这里插入图片描述
3. 核心流程:App被引入到了index.js里,然后被渲染到了public/index.html

二、JSX

  1. JSX是react编写UI模板的方式,表示在JS里编写HTML模板解构;
  2. 他不是标准的js语言,浏览器本身不能识别,需要通过解析后才能在浏览器里运行;
  3. JSX中{}里嵌入的是表达式,有值的语句才是表达式
  4. 如果表达式有空,布尔值,undefined他是不会显示的
  5. 直接设置标签时,style必须使用对象设置

2.1 Reat基础

2.1.1 生成列表

  • jsx自动将数组的元素在页面中显示
  • 使用array.map方法,循环列表,添加li
  • 生成列表的时候一定要个key
const arr  = ['猪八戒', '孙悟空', '唐僧', '沙和尚'];

const App = () => {
  return (
    <div className="App">
      <ul>{arr.map(item =><div>{item}</div>)}</ul>
    </div>
  );
}
  1. 使用for循环或者foreach
const arr  = ['猪八戒', '孙悟空', '唐僧', '沙和尚'];
const liList = [];

arr.forEach(item => {
  item.push(<li key={item}>{item}</li>);
});

2.1.1 大括号识别JS的表达式

  • 只能识别,表达式;if,switch等语句是无法识别的;
function App() {
  return (
    <div className="App">
      this is a react app
      {/* 使用引号传递字符串 */}
      {'This fxx'}
      {/* 识别JS变量 */}
      {num}
      {/* 函数,直接显示方法的返回值 */}
      {getName()}
      {/* 方法调用 */}
      {new Date().toLocaleTimeString()}
      {/* 使用js对象,驼峰 */}
      <div style = {{color: 'red', fontSize: '50px'}}> this is a red div </div>
    </div>
  )
}

2.1.2 生成列表

  • 注意:需要个key,不然console会报错;他的作用是提高性能;
const list =[
  {id:'1001',name:'tom'},
  {id:'1002',name:'jerry'},
  {id:'1003',name:'kitty'}
]

function App() {
  return (
    <div className="App">
      {list.map((item)=><li key={item.id}>{item.name}</li>)}
    </div>
  )
}

export default App;

2.1.3 条件渲染

const islogin = true

function App() {
  return (
    <div className="App">
      {islogin ? <h2>欢迎回来</h2> : <h2>请登录</h2>}
      {islogin&&<h2>用户名:{list[0].name}</h2>}
    </div>
  )
}

2.1.4 复杂条件渲染

  • 根据传来的listType,匹配不同的jsx的模板
const listType = 5

//根据listTpye,返回不同的jsx模板
function getListType() {
  if (listType === 0) {
    return <div>单图模式</div>
  }else if (listType === 1) {
    return <div>两图模式</div>
  }else if (listType === 2) {
    return <div>多图模式</div>
  }else {
    return <div>默认模式</div>
  }
}
const islogin = true

function App() {
  return (
    <div className="App">
      {getListType()}
    </div>
  )
}

2.2 组件

  • 组件可以让我们像搭积木一样,完成网页的监视
  • function + jsx, 开头大写,就被认为是组件
  • 组件可以直接用标签的形式渲染<Button/>
  • 通常情况下,一个组件就放在一个文件,文件名=组件名
  1. 编写一个NoteBook.js组件
const NoteBook = () => {
    return (
        <div className="logs">
        <div className="item">
            <div className="calendar">
	            <div className="month">4</div>
	            <div className="day">13</div>
            </div>
            <div className="content">
	            <h2>学习react</h2>
	            <p>40分钟</p>
            </div>
        </div>
        </div>
    );
}

export default NoteBook;

  1. 在根APP.js 引入
import  './index.css';
import NoteBook from './NoteBook';

const App = () => {
    return (
      <NoteBook/>
    )
}

export default App;

2.3 事件绑定

  • react中取消默认行为e.preventDefault()

2.2.1 给onclick绑定一个事件

  1. 给鼠标的onclick事件绑定一个方法
const handleclick = () => {
  alert('hello world')
}

function App() {
  return (
    <div className="App">
      <h1>hello world</h1>
      <button onClick={handleclick}>click me</button>
    </div>
  )
}

export default App;

2.2.2 获取点击事件 e

  1. 获取点击事件e
const handleclick = (e) => {
  return console.log(e)
}

2.2.3 传递自定义参数

  1. 传递自定义参数
  • 注意onClick后面的写法,必须使用箭头函数,延迟执行;如果直接传参调用,会在button创建的时候直接执行;
const handleclick = (name) => {
  return console.log(name)
}

function App() {
  return (
    <div className="App">
      <h1>hello world</h1>
      <button onClick={()=>handleclick('fxx')}>click me</button>
    </div>
  )
}

2.2.4 传递自定义参数+ e

  • 既传递自定义参数,也传递点击事件 e
const handleclick = (name,e) => {
  return console.log(name,e)
}

function App() {
  return (
    <div className="App">
      <h1>hello world</h1>
      <button onClick={(e)=>handleclick('fxx',e)}>click me</button>
    </div>
  )
}

2.4 props传递数据

  1. 添加需要传递的数据
import "./NoteBook.css";
import NoteItems from "./NoteItems";

const NoteBook = () => {
  return (
    <div className="logs">
      <NoteItems content="学习C#" stuTime="500小时" />
      <NoteItems content="学习英语" stuTime="1500小时" />
      <NoteItems content="学习前端" stuTime="100小时" />
    </div>
  );
};

export default NoteBook;

  1. 在另外的页面调用数据
function NoteItems(props) {
  console.log(props)
  return (
    <div className="item">
        <ItemCalendar />
    <div className="content">
      <h2>{props.content}</h2> 
      <p>{props.stuTime}</p>
    </div>
  </div>
  )
}

注意:props 只读属性

2.5 使用循环生成内容

  • 这里是手动添加的循环,实际我们需要模拟服务端来的数据;
    在这里插入图片描述
  • 模拟服务端的数据
const notBookJson = [
  {
    content: "学习英语",
    stuTime: 1500,
    month: "11月",
    day: 14,
  },
  {
    content: "阅读英文书籍",
    stuTime: 1200,
    month: "10月",
    day: 20,
  },
  {
    content: "练习听力",
    stuTime: 800,
    month: "9月",
    day: 5,
  },
  {
    content: "背诵单词",
    stuTime: 600,
    month: "11月",
    day: 1,
  },
];
  • 使用map循环数据
const addData = notBookJson.map((item) => (
  <NoteItems
    key={item.id}
    content={item.content}
    stuTime={item.stuTime}
    month={item.month}
    day={item.day}
  />
))

const NoteBook = () => {
  return (
    <div className="logs">
      {addData}
    </div>
  );
};

export default NoteBook;

2.6 Reack Hook

  1. React中的钩子函数只能用于函数组件或者自定义钩子中
  2. 钩子函数只能在函数组件内部调用,不能再外部调用

2.6.1 State

  • State是组件本身的状态,不能传递给其他组件;State是可变的,当Stage发生变化,会自动对该组件进行刷新,所以是写在组件内部的;
  • 在函数组件中,我们需要使用hook函数,获取State的;

2.6.2 useState 钩子函数

useState()

  1. 返回一个数组,第一个值是我们传递的值(字符串,array,function,class都可以);
  2. 第二个值是函数,通常命名为setXXXX,调用该函数setCounter(新值),修改state后,会触发组件重新渲染;并且将传入该函数的值,当作新的counter;
  3. 改的并不是当前的值,而是下一次渲染的值
  4. setState()他是异步渲染,当我们调用它,需要用旧的值时,会出现计算错误;为了避免这种情况,我们可以通过回调函数来设置setState();
const flag = 1
const [counter, setCounter] = useState(flag)
  • 点击按钮,页面数字翻倍
import "./App.css";
import React, { useState } from "react";

function App() {
  //设置一个初始状态,初始值为12,返回初始值和一个
  const [valueAdd1, setCount] = useState(12);

  //定义一个点击事件,每次点击给
  const handleClick = () => {
    setCount(valueAdd1 *2);
  };

  return (
    <div className="App">
      <button onClick={handleClick}>点击我,初始值+1</button>
      <div className="showValue">{valueAdd1}</div>
    </div>
  );
}

export default App;

2.7 使用ref获取原生DOM对象

了解

2.8 将css组件化(prop.children)

  • 该方案是将公共的css属性,放在一个div里,让这个div成为他们的父类

2.8.1 props默认传值

当组件中存在嵌套内容时,React 会自动将标签的内容,属性传递给props

const NoteBook = () => {
  return (
    <Card className="logs" style='fontSize:12px'>
      {addData}
    </Card>
  );
};
  • Card.js
function Card(props) {
  console.log(props)
  return (
    // <div className={'card ' + props.className}>
    <div className={`card ${props.className}`}>
        {props.children}
    </div>
  )
}
  • 在控制台看到,className, 所有的属性,已经标签的内容(这里是{addData}的列表) 都被当作了默认的数值传到了props
    在这里插入图片描述

2.8.2 提取公共的css

  • 我们将卡片的公共的css提取到Card.css
.card{
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0,0,0,0.2);
}
  1. 给盒子的外部,添加一个card的类名,这样就拥有了card以及原来的类的样式

旧版

2.4 useStage状态变量

  • useStage一个react hook函数,一旦状态变量发生改变,对应的视图UI也会发生改变(数据驱动)
import React, {useState} from 'react';

function App() {
  //1.定义状态变量
  const [count, setCount] = useState(0);

  //2.定义事件处理函数,修改状态变量
  const handleClick = () => {
    setCount(count + 1);
  }
  
  return (
    <div className="App">
        <button onClick={handleClick}>{count}</button>
    </div>
  )
}

2.5 基础样式控制

  1. 同级目录创建一个index.css文件
.foo{
    color: red;
    font-size: 50px;
}
  1. 将foo赋值给需要的类名
import './index.css'

function App() {

  return (
    <div className="App">
      <p className='foo'>hello world</p>
    </div>
  )
}

2.6 案例:b站评论

在这里插入图片描述
分析:

  1. 使用useState维护评论列表:因为评论是实时变化的,所以需要数据驱动UI
  2. 使用map方法对列表数据进行 遍历渲染

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部