最易懂-react18入门系列一

269 阅读6分钟

摘要

本篇主要是react基础篇。

  • 项目创建
  • jsx
  • 事件
  • 组件
  • useState响应式变量
  • 样式控制

react项目环境创建

利用cli可以快速搭建,react的cli工具叫:create-react-app,底层是基于webpack构建的,封装了配置细节,开箱即用。

  1. 执行 npx create-react-app yourProjectName

  2. npm run start 运行模板项目

  3. 清理不需要的文件,以及修改删减核心入口代码。

保留 public/src/index.js/app.js/package.json/lock/reamdme/gitignore文件,其他生成的文件可以删除。

修改index.js代码:

保留5行即可

// react 2个核心包导入
import React from 'react'
import ReactDOM from 'react-dom/client'

// 根组件
import App from './App'

// 拿到public/index.html 里的root 节点
const root = ReactDOM.createRoot(document.getElementById('root'))

// 把根组件挂载到root节点上后进行render渲染
root.render(<App/>)

jsx

jsx = js + html 的缩写。是自创的一种写法,既然是二者的结合,也就具备二者的优点。

它是react中编写UI模板的方式。在js中写html结构。

在jsx中是通过 {} 大括号来识别js的表达式的。如:变量、函数调用、js对象、字符串等。

jsx可以识别的东西:

function App(){
	return(

		<div>
			字符串:{'this is string'}
			变量:{count}
			函数调用:{getName()}
			内置方法调用:{new Date().getDate()}
			使用js对象<span style={{color:'#000'}}>span</span>
		</div>
	)
}

注意

if、for、Switch、变量声明等 属于语句的东西,是不能出现在{}里的,他只认识表达式!

优点

  1. 享有html声明式的模板写法。

  2. 享有js可编程的能力。

ps: 遇到dom标签用圆括号包裹,遇到js表达式用花括号包裹。

jsx本质

我们可以使用babel在线工具,写一段jsx,然后发现实际会转成jsx函数来调用,多层dom嵌套,就会有 多层的jsx函数嵌套来调用。

jsx如何写一个列表呢?

使用原生的map方法,循环哪个结构,return哪个结构,加上独一无二的key 是string 或者number类型。

return(
	<ul>
		{list.map(item => <li key={item.id}>{item.name}</li>)}
	</ul>
)

jsx中实现条件渲染

可以使用原生的 逻辑 && 或者 三元表达式 ?:

  1. 控制一个元素的显隐: &&
{flag && <span>一个元素</span?}
  1. 控制2个元素的显隐: ?:
{flag ? <span>1号元素</span> : <span>2号元素</span>}
  1. 控制多个元素的显隐:需要利用函数来分流返回不同的模板。
function chooseTpl(flag){
	if(flag == 1){
		return <div>tpl1</div>
	}else if(flag ==2 ){
		return <div>tpl2</div>
	}else{
		return <div>tpl3</div>
	}
}

事件绑定

1. 事件绑定

<button onClick={clickFn}>点击</button>

本文演示的代码案例均是核心代码片段,采用的都是函数式组件的写法。完整的代码机构基本如下:

function YourSelfComponent(){
	const clickFn = ()=>{console.log('点击回调')}

	return(
		<div className="YourSelfComponent">
			<button onClick={clickFn}>点击</button>
		</div>
	)
}

2. 获取事件对象e:

直接在函数定义位置,写 一个参数e来接收即可使用。

const clickFn = (e)=>{console.log('点击回调',e)}

3. 如果想传递自定义参数呢?

做编辑,删除时候常用。

绑定处,注意要改成箭头函数的写法,在执行回调实际处理业务函数的时候传递实参。

function YourSelfComponent(){
	const clickFn = (mode)=>{console.log('弹窗模式',mode)}

	return(
		<div className="YourSelfComponent">
			<button onClick={()=> clickFn('edit')}>编辑</button>
		</div>
	)
}

注意: 不能直接写函数调用,这里事件绑定需要一个函数引用。

4. 如果想用 事件对象e 还想要 自定义参数呢?

function YourSelfComponent(){
	const clickFn = (mode,e)=>{console.log('弹窗模式',mode,'事件对象',e)}

	return(
		<div className="YourSelfComponent">
			<button onClick={()=> clickFn('edit',e)}>编辑</button>
		</div>
	)
}

依然在绑定处使用箭头函数,然后参数传入和接收保持住一直的顺序。

组件

组件是一个通用的概念 哪个 框架里基本都有 组件化开发模式,它是不挑框架的。

概念:

一个组件就是一个页面的一个部分,它可以有自己的逻辑、外观,组件之间可以互相嵌套、也可以复用多次。

意义:

组件化开发可以让开发过程像 搭建积木一样构建一个完整庞大的应用。

分类:

通常在实际项目中,我们可能会把组件分为 "智能组件" 和 "UI组件"

  • 智能组件: 负责数据的获取。

  • UI组件: 负责数据的渲染。组件本身就是单纯的UI,里面展示什么数据,你是外界传入的。

React组件

在React中,组件首字母是需要大写的,它是一个函数,内部存放了组件的逻辑和UI。

渲染组件只需要把组件当成标签书写即可。

useState

是一个react hook函数,它允许我们向组件添加一个状态变量,从而控制影像组件的渲染结果。

本质:

和普通js变量不同的是,状态变量具有响应性,状态变量发生变化后,组件的视图是会同步更新变化的。

也就是数据驱动视图

const [num,setNum] = useState(0)

特性:

  1. useState 是一个函数,返回值是一个数组。
  2. 数组中的第一个参数是状态变量,第二个参数是set函数,用来修改状态变量的
  3. useState的参数将作为num的初始值。

使用useState实现一个计数功能

import {useState} from 'react'

function App(){
	//1.调用useState添加一个状态变量,num 是状态变量,setNum是修改状态变量的方法
	const [num,setNum] = useState(0)

	// 2. 点击 +1
	const clickFn = ()=>{
		setNum(num + 1)
		// num++ //错误
	}

	return(
		<button onClick={clickFn}>{num}</button>
	)
}

useState的修改规则

请记住 状态不可变性

不可变性具体是指 直接修改状态变量 ,是不会引发视图的更新的,也就是没有响应性的。必须通过调用配套的set方法,然后传入一个新值,react内部会用这个新值来替换掉旧值,从而引发视图更新。

如:我们把 setNum(num + 1) 写成 num++ 发现虽然num的值修改成功了,但是视图干脆不更新,

那么对于,对象来说呢,也是一样的道理,直接修改对象里的某个属性也是不生效的。react里推崇的思想是:

状态变量 不可修改,而是直接用新值做覆盖,才能更新!

对象类型的状态变量也是一样的规则:

import {useState} from 'react'

function App(){
	//1.调用useState添加一个状态变量,num 是状态变量,setNum是修改状态变量的方法
	const [dog,setDog] = useState({name:'jinmao',age:2})

	// 2. 点击 +1
	const clickFn = ()=>{
		//直接修改,❌
		// dog.name = 'jingba'

		// 传入一个全新对象去覆盖,✅
		setDog({
			...dog,
			name:'jingba'
		})
	}

	return(
		<button onClick={clickFn}>{num}</button>
	)
}

样式

react组件基础样式控制方式有两种方式:

方式一:行内样式(不推荐)

<div style="{{color:'#000'}}">div</div>

第一层括号,是识别js语法用的,第二层括号是一个json对象,里面一个个key,value键值对。多单词有连字符的改成驼峰形式。

方式二:class类名控制

import './style.css'

function YourSelfComponent(){
	return <div className='box'>div</div>
}

style.css文件:


.box{
	color:#000;
}

注意:

  1. react里不像原生里叫class属性,而是叫 className

  2. 对于多单词的css属性,style方式里需要写成小驼峰的形式

扩展

方式一也可以简单优化下:

const styles = {
	color:'#000',
	fontSize:'20px'
}

function YourSelfComponent(){
	return <div style={styles}>div</div>
}

把样式写一个对象,抽出去存到变量里。dom身上看着轻量一些。