React基础

1 篇文章 0 订阅
这篇博客介绍了如何使用两种方式创建React项目,并详细阐述了React页面的渲染过程,包括导入包、创建React元素和渲染到DOM。接着,讲解了JSX的规则和用法,以及条件渲染、事件处理和样式。然后,深入探讨了React组件,包括有状态和无状态组件,事件绑定,以及状态管理。最后,提到了React组件之间的通讯、Props的使用、生命周期方法以及React Hooks的基本概念。
摘要由CSDN通过智能技术生成

创建React项目

第一种方式

npm i -g create-react-app
//your-project-name 项目名称
create-react-app your-project-name

第二种方式

//your-project-name 项目名称
npx creat-react-app your-project-name

React页面渲染

步骤
1.导入包
2.创建react元素
3.渲染元素到某个dom上

React内置了JSX

1.jsx必须要有一个根节点
2.属性名不能用js中的关键字,例如class,for

//class类   写为className
<div className="App-header"></div>

3.单标签要闭合
4.换行建议使用()包裹
5.老版本(16.8)之前,先引入react才能使用jsx

jsx-嵌入表达式

<div>{}<div>

{}中可以写:
1.表达式
2.其他的jsx表达式
3.注释
不可以写:
1.对象
2.js语句 if/switch/变量申明

jsx条件渲染

if/else
三元运算符
逻辑与运算符
switch case

必须要有一个根节点

import React from 'react';
import ReactDOM from 'react-dom/client';

function App1() {
  // const num = Math.random()
  const flag = true
  const fn = () => {
    if(flag){
      return <p>成功</p>
    }else{
      return <p>失败</p>
    }
  }
  const skills = [
    {id:1,name:'html'},
    {id:2,name:'css'},
    {id:3,name:'js'}
  ]
  // const list = [
  //   <ol>技能{skills[0].id}:{skills[0].name}</ol>,
  //   <ol>技能{skills[1].id}:{skills[1].name}</ol>,
  //   <ol>技能{skills[2].id}:{skills[2].name}</ol>
  // ]
  // const list = skills.map(item => {
  //   return <ol key={item.id}>技能{item.id}:{item.name}</ol>
  // })
  const list = skills.map(item => <ol key={item.id}>技能{item.id}:{item.name}</ol>
  )
  
  return (
    <div className="App">
      {list}
      {fn}
    </div>
  );
}
const root = ReactDOM.createRoot(document.getElementById('root'));
//<React.StrictMode> 严格模式
root.render(
    	<App1></App1>
  );


jsx中的样式

 //style
 <div style={{position:'absolute',left:'10px'}} ></div>

//className
<div className = "mystyle"></div>

<style>
	.mystyle{
		position:'absolute',left:'10px'
	}
</style>

JSX中使用本地图片

import logo from './logo.svg';
<img src={logo} className="App-logo" alt="logo" />

React组件

组件类型

1.基础组件
2.业务组件
3.区块组件
4.页面组件

React创建组件的两种方式

1.函数式组件(js是函数或箭头函数)

约定1.函数首字母大写
约定2.必须有返回值

  const Com1 = ()=> {
    return <div>函数组件</div>
  }
2.类组件

注意:
1.类名必须以大写字母开头
2.render必须要有返回值

   class Com2 extends React.Component {
        render () {
            return <div>类组件</div>
        }
    }

React有状态组件和无状态组件

状态:是用来描述事物在 某一时刻的形态 的 数据,一般称为state
状态的特点:状态能被改变,改变之后视图会对应的变化

有状态组件

能够定义state的组件,类组件就是有状态的组件
创建state第一种方式:

import React from 'react';
import ReactDOM from 'react-dom/client';

// 类组件
class Com2 extends React.Component {
  state = {
	  num:100,
	  obj:{
	     name:'小花'
	  }
  }
  render () {
    const { num, msg, obj } = this.state
    return (
      <div>
        <p>num:{num}</p>
        <p>msd:{msg}</p>
        <p>obj的名字:{obj.name}</p>
      </div>
    )
  }
}

创建state第二种方式:

import React from 'react';
import ReactDOM from 'react-dom/client';

// 类组件
class Com2 extends React.Component {
  constructor (){
    super()
    this.state ={
      num:1,
      msg:'状态信息',
      obj:{
      	name:'小花'
      }
    }
  }
  render () {
    const { num, msg, obj } = this.state
    return (
      <div>
        <p>num:{num}</p>
        <p>msd:{msg}</p>
        <p>obj的名字:{obj.name}</p>
      </div>
    )
  }
}

无状态组件

不能定义state的组件,函数组件又叫无状态组件
应用场景:
1.组件本身不需要状态,例如渲染一段固定内容
2.组件本身没有状态,可以从外部传入

React中事件绑定

//语法
<元素 事件名1={ 事件处理函数1 } 事件名2={ 事件处理函数2 }>
class Com2 extends React.Component {
  onClick () {
  	console.log('修改状态')
  }
  render () {
    const { num, msg, obj } = this.state
    return (
      <div>
        <button onClick={this.hClick()}>修改状态</button>
		//上面一句代码 等价下一句代码
		<button onClick={undefined}>修改状态</button>
      </div>
    )
  }
}

注意:
1.React事件名采用驼峰命名法
2.在类中补充方法
3.this.fn不要加括号

事件对象

class Com2 extends React.Component {
  hClick (e) {
  	//阻止默认行为
  	e.preventDefault()
  	//阻止冒泡行为
  	console.log('修改状态')
  }
  render () {
    return (
      <div>
        <button onClick={this.hClick}>修改状态</button>
      </div>
    )
  }
}

事件中this的指向

class Com2 extends React.Component {
  hClick( e) {
  	console.log(this)  //undefined
  }
  render () {
  	console.log(this)  //
    return (
      <div>
        <button onClick={this.hClick}>修改状态</button>
      </div>
    )
  }
}

class内部启用了严格模式
render方法指向当前react组件

解决React事件处理程序中this指向问题主要有三种方式:

1.在外层补充箭头函数
2.Function.prototype.bind()
3.class的实例方法(推荐)

 {/* 在外层补充箭头函数 */}
 <button onClick={()=>{this.h2()}}>点我-箭头函数</button>
 {/* bind */}
 <button onClick={this.h3.bind(this)}>点我-bind</button>
  {/* 实例方法 */}
  <button onClick={this.h4}>点我-bind</button>

react 核心理念状态不可变

不能直接修改state改变视图,需要通过setState()修改状态

class Com2 extends React.Component {
  constructor (){
    super()
    this.state ={
      num:1
    }
  }
  hClick = () => {
    this.setState({
      num: this.state.num+1
    })
  }
  render () {
  	const { num } = this.state
    return (
      <div>
       <p>num:{num}</p>
        <button onClick={this.hClick}>修改状态</button>
      </div>
    )
  }
}

非受控组件-ref

借助 ref,使用原生DOM的方式来获取表单元素的值。使用步骤如下:
1.导入方法: import { createRef } from 'react';
2.调用createRef方法创建引用, 假设名为refDom , const refDom = createRef()
3.refDom设置给表单元素的ref属性 ,<input ref={refDom} >
4.通过refDom.current.value来获取值,

//class组件
class Com2 extends React.Component {
  refDom = createRef()
  constructor (){
    super()
    this.state ={
      num:1
    }
  }
  fn(){
    console.log('点击',this.refDom.value)
  }
  render () {
    return (
      <div>
        <input ref={this.refDom} type="text"></input>
        <button onClick={()=>{this.fn()}}>点击按钮</button>
      </div>
    )
  }
}

// 函数组件
const Com1 = ()=> {
  const refDom = createRef()
  const fn = () => {
    console.log('点击',refDom.current.value)
  }
  return (<div>
    函数组件
    <input type="text" ref={refDom} />
    <button onClick={fn}>点击按钮</button>
  </div>)
}

受控组件

使用受控组件的方式获取表单的值
正常情况下,表单元素input是可用任意输入内容,可用理解为input自己维护它的状态(value)
受控组件的思路:
1.在state中定义状态
2.将state中的状态与表单元素的value绑定在一起,进而通过state中的状态来控制表单元素

//class组件
class Com2 extends React.Component {
  refDom = createRef()
  constructor (){
    super()
    this.state ={
      msg:''
    }
  }
  fn2 = (e)=>{
    this.setState({
      msg:e.target.value
    })
  }
  render () {
   const { msg } = this.state
    return (
      <div>
      	<input onChange={this.fn2} type="text" value={this.state.msg}></input>
      </div>
    )
  }
}

React组件

组件拆分到文件

1.创建组件

//Header.js
import React, { Component } from 'react'
export default class Header extends Component {
  render() {
    return (
      <div>
        这是一个组件
      </div>
    )
  }
}

2.使用组件

import Header from './Header';
//部分代码
 return (
    <div className="App">
      <Header />
    </div>
  );

React组件通讯的三种方式

1.父子组件之间
父传子 props

父组件-传入数据

<子组件 自定义属性1={1} 自定义属性1={2}>
export default class Parents extends Component {
  render() {
    return (
      <div>
        父组件
        <Son age={18} name="小花" />
      </div>
    )
  }
}

函数式子组件接受数据:props

function Son(props){
	return <div>子组件</div>
}

Class子组件接受数据:this.props

//类组件部分代码
render() {
    const { age, name } = this.props
    return (
        return <div>子组件</div>
    )
}
子传父 props

利用回调函数,父组件提供回调,子组件调用,将传递的数据作为回调函数的参数。

//父组件
export default class Parents extends Component {
  state = {
  	num:1
  }
  f = (num) =>{
  	this.setState({num})
  }
  render() {
    return (
      <div>
        {this.state.num}
         <Son f={this.f} />
      </div>
    )
  }
}

Class子组件接受数据:this.props

//子组件部分代码
hClick = () =>{
	this.props.f(1)
}
render() {
    const { age, name } = this.props
    return (
        return (<div>
        <button onClick={this.hClick}>1传给父组件</button>
        </div>)
    )
}
2.兄弟组件之间
	状态提升,定义在子组件状态,提升到父组件中,以父组件作为桥梁,让兄弟之间进行通讯。
//父组件
export default class Parents extends Component {
  state = {
  	num:1
  }
  f = (num) =>{
  	this.setState({num})
  }
  render() {
    return (
      <div>
        {this.state.num}
         <Son1 f={this.f} />
         <Son2 num={this.state.num} />
      </div>
    )
  }
}
//子组件部分代码
hClick = () =>{
	this.props.f(1)
}
render() {
    const { age, name } = this.props
    return (
        return (<div>
        <button onClick={this.hClick}>1传给父组件</button>
        </div>)
    )
}
//son1子组件部分代码
hClick = () =>{
	this.props.f(1)
}
render() {
    const { age, name } = this.props
    return (
        return (<div>
        <button onClick={this.hClick}>1通过父组件传给兄弟组件</button>
        </div>)
    )
}
//son2子组件部分代码
render() {
    return (
        return (<div>
        {this.props.num}
        </div>)
    )
}
3.跨组件层级Context()
import { createContext } form  'react'
const { Provider, Consumer } = createContext()

Provider包裹根组件

 return (
    <div>
     // store={store}  需要传的值
    <Provider store={store}>
      <App></App>  
    </Provider>
    
    </div>
  )

任意后代组件,可使用Consumer组件包裹整个组件

render(){
 return (
    <Consumer>
  		{
  			(data) => {
  				return <div>这里是组件的内容,data是传过来的数据</div>
  			}
  		}
    </Consumer>
  )
}

React中 props基本使用

使用props语法能够将数据从父组件传到子组件

props注意事项:
1.可以传递任意数据(包括函数,jsx)
2.props是只读属性(不可以修改)
数据是谁的谁去改
3.单向数据流 自上而下

props中的children属性 (传结构)

只要组件有子节点,props就有该属性

<Girl age={18} name="小花">
   <h5>h5标签</h5>
 </Girl>
 //props.children
//Girl 组件
function Girl(props){
	return <div>{props.children}</div>
	//等价 <div><h5>h5标签</h5></div>
}
//可以传结构

propstype 校验

improt PropTypes from 'prop-types'
// App为组件的名字
App.propsTypes = {
	pagesize:PropTypes.number
}
props给组件设置默认值 的两种方式

1.defaultProps

//组件App部分代码
// App为组件的名字
App.propsTypes = {
	pagesize:PropTypes.number
}

2.结构赋值的默认值

const {pagesize=10} = this.props
//组件App部分代码
//设置默认值
APP.defaultProps = {
    pagesize:10
}

React生命周期

执行时机:组件创建时(页面加载时)

生命周期

挂载时:
constructor()---->render()---->ComponentDidMount()

1. constructor()
创建组件时最先执行
作用:1.初始化state 2.创建Ref
2. render()
每次组件渲染都会触发
作用:渲染ui
3.ComponentDidMount()
组件挂载(完成DOM渲染)后
作用:1.发送网络请求 2.DOM操作

更新时
render()----> ComponentDidUpdate()

三种情况下可以导致更新 new props(父组件传入的数据发生改变) 、 this.setState()this.forceUpdate()

卸载时
ComponentWillUnmount()

可以清除定时器 移除事件 比如监听器

setState

this.setState(
  { link: 'http://www.chao99.top' },
  () => console.log('这是回调函数')
)

setState三个特点

  1. 可以表现为异步
    setState调用之后,并不会立即去修改state的值,也不会立即更新DOM
  2. 多次调用会合并,统一后触发一次render()
  3. 使用不当会造成死循环 在render()ComponentDidUpdate()中调用setState()会导致死循环

setState第二个参数是回调函数

该函数会在setState函数调用完成并且组件开始重渲染的时候被调用,我们可以用该函数来监听渲染是否完成

React hooks

hooks 是一些函数 可以让在函数组件中“钩入”React state及生命周期的新特性
hooks只能在函数组件使用
hooks和现有代码可以同时工资,可以渐进式地使用
hooks带来了更强大的逻辑复用

useState修改函数组件状态

格式一:

const res = useState(100)
const [count,setCount] = res

格式二:

  const [content,setContent] = useState(()=>{
      return 'abc'
  })

useState函数中:可以计算、localStorage拿值

注意:
1.只能出现在函数组件内部
2.useState不能使用if或for中,如果存在无法知道调用的是哪个hooks

userffect 理解副作用

函数式组件中
主作用:根据数据渲染ui
副作用:数据请求,手动修改DOM、localstorage操作等

userEffect挂载和更新时会执行

userEffect(()=>{
    //事件绑定,请求数据

},[])
//n改变执行
userEffect(()=>{

},[n])
// 参数为空,只执行一次
userEffect(()=>{

},[])

n变化执行(依赖项变),依赖项可以多个

副作用函数 返回值

返回值可以清理副作用
清理函数会在组件卸载以及下一次副作用函数调用前执行

 useEffect(()=>{
      setInterval(()=>{
        setCount((count)=>count - 1)
      },1000)
      return ()=>{
        console.log('清理副作用')
      }
  },[])

useEffect可以模拟函数钩子

自定Hooks

逻辑复用
自定义Hooks 名字用use开头
只能在函数组件或自定义hooks中调用

useRef

使用场景:在React中进行DOM操作时,用来获取DOM
作用:
1.返回一个带有current属性的可变对象,通过该对象可以进行DOM操作
2.多次渲染中共享数据

  import { useEffect, useRef, useState } from 'react'
  const refTimerId = useRef(null)
  
  //部分代码
  const hClick = () =>{console.log(refTxt.current.value)}
   <input ref={refTxt} />
   <button onClick={this.hClick}>点击获取input中的值</button>
useContext 全局状态

跨组件通讯

// index.js 根组件
import React, { useState,createContext } from 'react'
import Father from './Father'

export  const Context = createContext()
export default function Index() {
    const [color,setColor] = useState('red')
    return (
        <Context.Provider value={color}>
             <div style={{border:'1px solid #ccc',margin:40}} >
            根组件:
            color:{color}
            <button onClick={()=>{
                setColor('green')
            }}>
                改成green
            </button>
            <Father></Father>
            </div>
        </Context.Provider>
   
  )
}
//Father组件
import React from 'react'
import Son from './Son'

export default function Father() {
  return (
    <div style={{border:'1px solid #ccc',margin:10}}>
      父组件
      <Son></Son>
    </div>
  )
}
import React,{useContext} from 'react'
import {Context} from './index'
function Son() {
  const res = useContext(Context)
  return (
    <div style={{border:'1px solid #ccc',margin:10}}>
      子组件:color:{res}
    </div>
  )
}

export default Son

Redux

多组件共享数据
安装redux

npm i redux

redux核心概念:

1.store
2.action
3.reducer

react-redux

npm i react-redux
reducer分离

combineReducers 合并reducer

纯函数

相同的输入总是得到相同的结果
reducer也是纯函数

拓展优化 action-creator
优化 action-type

redux-中间件-redux-thunk

支持dispatch函数格式

npm i redux-thunk

redux-中间件-redux-logger

npm i redux-logger

redux调试工具

未完,持续更新…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值