react入门到实战-day2-7.21

昨天晚上刚学完已经一点了,来不及写笔记,主要是想睡觉哈,所以今天补上,我发现效率还挺高的,今天重新做笔记,加固了昨天的知识点,要不以后都这样子哈,学完第二天再写哈,要是大家有推荐的vue项目练手可不可以分享给我,跪求


React表单控制

受控绑定

概念:使用React组件的状态(useState)控制表单的状态

受控表单:

第一步:声明一个react状态--useState

第二步:通过value属性绑定react状态

第三步:绑定onChange事件,通过事件参数e拿到输入框的最新值,反向修改到react状态中

import {useState} from 'react'
function App(){
  const [value, setValue] = useState('')
  return (
    <input 
      type="text" 
      value={value} 
      onChange={e => setValue(e.target.value)}
    />
  )
}

非受控绑定

概念:通过获取DOM的方式获取表单的输入数据

react 获取dom

第一步:useRef生成ref对象,绑定到dom标签上

第二步:dom可用时(渲染完毕之后dom生成之后才可用),ref.current获取dom

import {useRef} from 'react'
function App(){
  const inputRef = useRef(null)

  const onChange = ()=>{
    console.log(inputRef.current.value)
  }
  
  return (
    <input 
      type="text" 
      ref={inputRef}
      onChange={onChange}
    />
  )
}


React组件通信

概念:组件通信就是组件之间的数据传递, 根据组件嵌套关系的不同,有不同的通信手段和方法

父子通信-父传子

实现步骤

  1. 父组件传递数据 - 在子组件标签上绑定属性

  2. 子组件接收数据 - 子组件通过props参数接收数据

  3. props:对象里面包含了父组件的传递过来的所有数据

function Son(props){
  return <div>{ props.v }</div>
}

function App(){
  const name = 'this is app name'
  return (
    <div>
       <Son v={name}/>
    </div>
  )
}

props说明

props可以传递任意的合法数据,比如数字、字符串、布尔值、数组、对象、函数、JSX

props是只读对象子组件只能读取props中的数据,不能直接进行修改, 父组件的数据只能由父组件修改


父传子 - 特殊的prop children

当我们把内容嵌套在组件的标签内部时,组件会自动在名为children的prop属性中接收该内容



父子通信-子传父

核心思路:在子组件中调用父组件中的函数并传递参数

首先给子组件标签传递一个父组件中的函数,传过去之后子组件接收,在子组件通过某些事件调用起来,同时把自己的数据当作实参,传给父组件,父组件中的函数写一个形参接收

function Son({ onGetMsg }){
  const sonMsg = 'this is son msg'
  return (
    <div>
      {/* 在子组件中执行父组件传递过来的函数 */}
      <button onClick={()=>onGetMsg(sonMsg)}>send</button>
    </div>
  )
}


function App(){
//加一个状态数据
const {value,setSa}=useState('')

  const getMsg = (msg)
  =>{
  	console.log(msg)
  	setSa(msg)
  }
  
  return (
    <div>
      {/* 传递父组件中的函数到子组件 */}
       <Son onGetMsg={ getMsg }/>
       
       {msg}
       
    </div>
  )
}


兄弟组件通信

实现思路: 借助 状态提升 机制,通过共同的父组件进行兄弟之间的数据传递

  1. A组件先通过子传父的方式把数据传递给父组件App

  2. App拿到数据之后通过父传子的方式再传递给B组件

// A->App 
import { useState } from "react"

function A({ i }) {
  const n = 'this A'
  return (
    <div>
      this is A compnent,
      <button onClick={() => i(n)}>123</button>
    </div>
  )
}

function B() {
  return (
    <div>
      this is B compnent,

    </div>
  )
}

function App() {
  const [name, setAa] = useState

  const getAname = (name) => {
    setAa(name)
    console.log(name);
  }
  return (
    <div>
      this is App
      <A i={getAname}></A>

    </div>
  )
}

export default App

// A->App App->B
import { useState } from "react"

function A({ i }) {
  const n = 'this A'
  return (
    <div>
      this is A compnent,
      <button onClick={() => i(n)}>123</button>
    </div>
  )
}

// 解构出来的x
function B({ x }) {
  return (
    <div>
      this is B compnent,
      {x}
    </div>
  )
}

function App() {
  // 要想把a的数据传给B,则app要准备一个数据用来接受a传过来的数据,
//并且希望b可以动态的显示这个数据,则需要状态变量
  const [name, setAa] = useState('')

  const getAname = (name) => {

    console.log(name);

    setAa(name)
  }
  return (
    <div>
      this is App
      <A i={getAname}></A>
      <B x={name}></B>
    </div>
  )
}

export default App


跨层组件通信

实现步骤:

  1. 使用 createContext方法创建一个上下文对象Ctx

  2. 在顶层组件(App)中通过 Ctx.Provider 组件提供数据

  3. 在底层组件(B)中通过 useContext 钩子函数获取消费数据

//App->A->B

import { createContext, useContext } from "react"

// 1. createContext方法创建一个上下文对象
const Asdf = createContext()

function A() {

  return (
    <div>
      this is A compnent,
      <B></B>
    </div>
  )
}


function B() {
// 3. 在底层组件 通过useContext钩子函数使用数据
  const qwe = useContext(Asdf)
  return (
    <div>
      this is B compnent,{qwe}

    </div>
  )
}

function App() {
  const qwe = 'this App'
  return (
    <div>
    
     {/* 2. 在顶层组件 通过Provider组件提供数据 */}
      <Asdf.Provider value={qwe}>
        this is App
        <A></A>
      </Asdf.Provider>

    </div>
  )
}

export default App


React副作用管理-useEffect

概念理解

useEffect是一个React Hook函数,用于在React组件中创建不是由事件引起而是由渲染本身引起的操作(副作用), 比如发送AJAX请求,更改DOM等等

说明:

  1. 参数1是一个函数,可以把它叫做副作用函数,在函数内部可以放置要执行的操作

  2. 参数2是一个数组(可选参),在数组里放置依赖项,不同依赖项会影响第一个参数函数的执行,当是一个空数组的时候,副作用函数只会在组件渲染完毕之后执行一次

import { useEffect, useState } from 'react'

const URL = 'http://geek.itheima.net/v1_0/channels'

function App() {

  // 之后才创建一个状态
  const [list, setSt] = useState([])

  useEffect(() => {
    async function getL() {
      const res = await fetch(URL)
      const i = await res.json()
      console.log(i);

      setSt(i.data.channels)
    }
    getL()
  }, [])

  return (
    <div>

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

      </ul>

    </div>
  )
}

export default App

useEffect依赖说明

useEffect副作用函数的执行时机存在多种情况,根据传入依赖项的不同,会有不同的执行表现

依赖项副作用功函数的执行时机
没有依赖项组件初始渲染 + 组件更新时执行
空数组依赖只在初始渲染时执行一次
添加特定依赖项组件初始渲染 + 依赖项变化时执行
import { useEffect, useState } from 'react'

function App() {
 

  const [count, setCount] = useState(0)


  //useEffect(() => {
   // console.log('fu');
  //})
  
   // useEffect(() => {
  //   console.log('fu');
  // }, [])

  useEffect(() => {
    console.log('fu');
  }, [count])

  return (
    <div>
      this is app
      <button onClick={() => setCount(count + 1)}>++{count}</button>
    </div>
  )
}

export default App

清除副作用

概念:在useEffect中编写的由渲染本身引起的对接组件外部的操作,社区也经常把它叫做副作用操作,比如在useEffect中开启了一个定时器,我们想在组件卸载时把这个定时器再清理掉,这个过程就是清理副作用

说明:清除副作用的函数最常见的执行时机是在组件卸载时自动执行

import { useEffect, useState } from "react"

function Son () {
  // 1. 渲染时开启一个定时器
  useEffect(() => {
    const timer = setInterval(() => {
      console.log('定时器执行中...')
    }, 1000)

    return () => {
      // 清除副作用(组件卸载时)
      clearInterval(timer)
    }
  }, [])
  return <div>this is son</div>
}

function App () {
  // 通过条件渲染模拟组件卸载
  const [show, setShow] = useState(true)
  return (
    <div>
      {show && <Son />}
      <button onClick={() => setShow(false)}>卸载Son组件</button>
    </div>
  )
}

export default App

 


自定义Hook实现

概念:自定义Hook是以 use打头的函数,通过自定义Hook函数可以用来实现逻辑的封装和复用

import { useEffect, useState } from 'react'


function App() {
  const [show, setShow] = useState(true)

  const v = () => setShow(!show)

  return (
    <div>
      {show && <div>显示与隐藏</div>}
      <button onClick={v} >asd</button>

    </div>
  )
}

export default App

封装自定义hook通用思路

1. 声明一个以use打头的函数

 2. 在函数体内封装可复用的逻辑(只要是可复用的逻辑)

 3. 把组件中用到的状态或者回调return出去(以对象或者数组)

4. 在哪个组件中要用到这个逻辑,就执行这个函数,解构出来状态和回调进行使用
 

import { useEffect, useState } from 'react'

// 封装自定义Hook

// 问题: 布尔切换的逻辑 当前组件耦合在一起的 不方便复用

// 解决思路: 自定义hook


function useToggle() {

  // 可复用的逻辑代码
  const [show, setShow] = useState(true)

  const v = () => setShow(!show)

  // 哪些状态和回调函数需要在其他组件中使用 return
  return { show, v }

}


function App() {

  const { show, v } = useToggle()

  return (
    <div>
      {show && <div>显示与隐藏</div>}
      <button onClick={v} >asd</button>

    </div>
  )
}

export default App

React Hooks使用规则

  1. 只能在组件中或者其他自定义Hook函数中调用

  2. 只能在组件的顶层调用,不能嵌套在if、for、其它的函数中

 


  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值