React(二)——dom、组件间通信、useEffect

目录

一、表单受控绑定

二、React中获取DOM

三、组件间通信

1.父传子

特殊的prop------children

2.子传父

3.兄弟间组件通信

(1)儿子A给父通信,然后父再把拿到的数据传给儿子B

(2)Context机制跨层级组件通信(从上到下)

四、useEffect

1.基础

2.不同依赖项

3.useEffect清除副作用

五、自定义Hook实现


一、表单受控绑定

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

就是你往input里输入内容,然后state用onChange 事件监听到输入框内容变化,于是用setName更改name属性,也就是这个变量值变了,然后数值驱动试图,input框里的内容跟着显示出来。

(虽然输入框显示键盘输入的内容是浏览器的默认行为,但是这个默认行为下js并不知道你写了什么,除非document.xx去获取。但是这种表单受控绑定的情况下react就知道你写了什么并且由他给你展示在页面上)

(展示动作是浏览器完成的,展示什么内容是react决定的)

复制代码
import { useState } from "react";

function Son() {
  const [name,setName]=useState('')
  const setName1=(value)=>{
    setName(value)
  }
  const nameChange=(e)=>{
    console.log(e.target.value)
    setName1(e.target.value)
  } 
  return (
    <div>
       <input onChange={
        nameChange
       } value={name}></input>
    </div>
  );
}

export default Son;

二、React中获取DOM

目前基本都是要数据驱动视图,不建议直接去操作dom,但是某些情况需要我们操作dom,需要使用useRef钩子函数

  1. 使用useRef创建Ref对象,并与JSX绑定

  2. ref.current获取dom值

    import { useState } from "react";
    import { useRef } from "react";

    function Son1() {
    //获取ref对象,初始值为null,并把这个对象绑定到dom身上去
    const inputRef=useRef(null)
    //然后这个对象.current获取dom
    console.log(inputRef.current)
    return (


    <input ref={inputRef} value={'11'}>

    );
    }

    export default Son1;

不过需要注意第二步在dom渲染完毕的时候才能用

三、组件间通信

1.父传子

依旧是标签给子传,子用props接收

父:

复制代码
import { useState } from "react";
import Son1 from './components/Son1'

function App() {
  return (
    <div>
       <Son1 name={'hh'} />
    </div>
  );
}

export default App;

子:(props接收来的数据只读)

复制代码
import { useState } from "react";

function Son1(props) {
  console.log(props,'99')
  return (
    <div>11</div>
  );
}

export default Son1;

props是个对象

可以传递数字、字符串、布尔、数组、对象、函数、JSX

特殊的prop------children

把内容直接嵌套在子组件标签里,然后在子组件的pros.children里去找

复制代码
<Son1>
   <span>111 </span>
</Son1>

2.子传父

依旧是子调用父的方法

父:

复制代码
import { useState } from "react";
import Son1 from './components/Son1'


const fn_f=(x)=>{
  console.log(x,'888')
}


function App() {
  return (
    <div>
       <Son1 fn_f={fn_f}></Son1>
    </div>
  );
}

export default App;

子:

复制代码
import { useState } from "react";
import { useRef } from "react";

function Son1(props) {
  console.log(props,'99')
  props.fn_f('hhh')
  return (
    <div>
       111
    </div>
  );
}

export default Son1;

注意:useState 必须写在 function 组件名() {} 的函数体内部

3.兄弟间组件通信

(1)儿子A给父通信,然后父再把拿到的数据传给儿子B

比较简单就不再放代码了

(2)Context机制跨层级组件通信(从上到下)

  • 使用createContext方法创建一个上下文对象Ctx
  • 在顶层组件用Ctx.provider组件提供数据
  • 底层组件通过useContext钩子函数获取数据

顶级组件:

复制代码
import { useState } from "react";
import Son1 from './components/Son1'
import Son2 from './components/Son2'
import { createContext } from "react";

const msg="Hello React!";

export const Ctx=createContext()


function App() {
  return (
    <div>
       <Son1 fn_f={fn_f}></Son1>
       <Ctx.Provider value={msg}>
         <Son2></Son2>
       </Ctx.Provider>
    </div>
  );
}

export default App;

底层组件:

复制代码
import { useContext, useState } from "react";
import { useRef } from "react";
import { Ctx } from "../App";

function Son2(props) {
  const btn=()=>{
    // console.log(props,'99')
   
  }
   const msg = useContext(Ctx);
    console.log(msg,'99')
  return (
    <div>
       <input onClick={btn}></input>
    </div>
  );
}

export default Son2;

我是在两个文件里写的,所以Ctx还需要导出导入一下,不过我感觉特别不好,我都导出了还要你Context干嘛(不过export导出的变量组件不能监听变化以及自动更新,而context可以)

四、useEffect

1.基础

useEffect是一个React的React Hook函数,用于在组件中创建不是由事件引起而是由渲染本身引起的操作,比如发送AJAX请求、更改DOM(就像mounted干的事一样,用户没有任何操作,但是渲染完了就自动去发请求)

复制代码
userEffect(()=>{},[])

第一个参数是一个箭头函数,也叫副作用函数,放要执行的操作

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

2.不同依赖项

第一种是这个参数压根不传,组件更新指的是组件函数重新渲染了一次,比如state变化、props变化、父组件重新渲染了

第三种比如下面这种,只有count和name变化之后才会有hh输出

复制代码
userEffect(()=>{
    console.log('hh')
},[conut,name])

3.useEffect清除副作用

就像定时器在vue里要在组件卸载的时机去清理一样,语法:

复制代码
userEffect(()=>{
    //副作用代码(订阅、定时器、事件监听等)
    return()=>{
    //清除副作用逻辑
    }
},[])

所以这个userEffect类似mounted(但又不仅仅是mounted,还有点监听器的作用),里面的return类似unmounted

五、自定义Hook实现

自定义Hook是以use打头的函数,通过自定义Hook函数可以用来实现逻辑的封装和复用,就是用use打头命名的一个function,最后把需要的东西return出去供组件或其他Hook函数使用。

ReactHooks使用规则(这里不只自定义的,还有useStateuseEffectuseContextuseRefuseReduceruseCallbackuseMemo 等等):

  1. 只能在组件或其他Hook函数使用
  2. 只能在组件的顶层调用,不能嵌套在if、for、其他函数中(React靠调用次序来记住Hooks,而不是靠名字,如果放if/for/其他函数里的话就会搞混顺序)
相关推荐
ly76892 小时前
HTML5 从入门到工程实践:语义化、表单、多媒体、性能与项目规范详解
前端·html·html5
人民广场吃泡面6 小时前
前端该重视的编程思想
前端
冬夜戏雪6 小时前
agent的trace 和eval
开发语言·前端·javascript
IT_陈寒6 小时前
Redis的DEL命令居然没删干净数据?这个坑我爬了半天
前端·人工智能·后端
kyriewen6 小时前
面试官让我现场用 AI 改一个真实 bug——他打断我的 3 个理由
前端·面试·ai编程
计算机魔术师7 小时前
斯坦福研究:AI 对入门级岗位冲击最大
前端
感谢一路走过的人7 小时前
AGGrid刷新数据后执行筛选
javascript·ag-grid
水獭比特7 小时前
工具都批准了,为什么还不能执行?给 Agent 补上第二道校验
javascript·人工智能·node.js