React学习 day1-2

104 阅读5分钟

React learning

day1

JSX

{/* 使用引号传递字符 */}
{'this is an App '}

{/* 使用js变量 */}
{count}

{/* 函数调用和方法调用 */}
{getName()}
{new Date().getDate()}

{/* 使用js对象 */}
<div style={{color:'red'}}>hihihi</div>

注意:if语句 switch语句 变量声明属于语句 不是表达式 不能出现在{}中

实现渲染列表

const list = [
    { id:1001, name:'wcn'},
    { id:1002, name:'jcc'},
    { id:1003, name:'ys'},
]
function App() {
  return (
    <div className="App" >
        this is an App
        {/* 列表渲染 */}
        {/* map循环哪个结构 return结构 */}
        {/* 注意事项: 加上一个独一无二的key 字符串或者number */}
        {/* 作用react内部使用提高更新性能*/}
        <ul>
            {list.map(item => <li key={item.id}>{item.name}</li>)}
        </ul>
    </div>
  );
}

实现渲染条件

const isLogin = true;
function App() {
  return (
    <div className="App" >
      {/* 逻辑与 && */}
      {isLogin && <span>this is span</span>}
      {/* 三元运算 */}
      {isLogin ? <span>Jack</span> : false}
    </div>
  );
}
export default App;

实现复杂渲染条件

const nameType = 3; // 0 1 3
const getName = ()=>{
  if (nameType === 0){
    return <div>没名字</div>
  }else if (nameType === 1){
    return <div>我有一个名字</div>
  }else if (nameType === 3){
    return <div>我有好多名字</div>
  }
}
function App() {
  return (
    <div className="App" >
      {getName()}
    </div>
  );
}
export default App;

事件绑定

//基础绑定
// const handleClick = ()=>{
//     console.log('button 被点击了')
// }

//事件参数e
// const handleClick = (e)=>{
//     console.log('button 被点击了',e)
// }

//传递字段定义参数
//const handleClick = (name)=>{
//     console.log('button 被点击了',name)
// }

//同时传递事件对象和自定义参数
const handleClick = (name,e)=>{
    console.log('button 被点击了',name,e)
}
function App() {
  return (
    <div className="App" >
      <button onClick={(e)=>handleClick('jack',e)}>button</button>
    </div>
  );
}
export default App;

React组件

const Button = ()=>{
    return <button> click me! </button>
}
function App() {
  return (
    <div className="App" >
        {/* 自闭和 */}
        <Button/>
        {/* 成对标签 */}
        <Button></Button>
    </div>
  );
}
export default App;

useState基础使用

useState是一个 React Hook(函数), 它允许我们向一个组件添加一个状态变量,从而控制影响组件的渲染效果

  1. useState是一个函数,返回值是一个数组
  2. 数组中的的第一个参数是状态变量,第二个参数是set函数用来修改状态变量
  3. useState的参数将作为count的初始值
import {useState} from "react";
function App() {
  const [count,setCount] = useState(0)
    const handleClick = ()=>{
      setCount(count + 1)
    }
  return (
    <div className="App" >
      <button onClick={handleClick}>{count}</button>
    </div>
  );
}
export default App;

修改状态规则

import {useState} from "react";

function App() {
    const [count, setCount] = useState(0)
    const handleClick = () => {
        setCount(count+1)
    }
    const [form, setForm] = useState({name: 'Jack'})
    const changeForm = () => {
        setForm({
            ...form,
            name: 'John',
        })
    }
    return (
        <div className="App">
            <button onClick={handleClick}>click me {count}</button>
            <button onClick={changeForm}>修改form{form.name}</button>
        </div>
    );
}

export default App;

组件基础样式方案

import "./index.css"
const style = {
    color: 'red', fontSize: '100px'
}

function App() {
    return (
        <div>
            {/* 通过行内样式控制 */}
            <span style={style}>div</span>
            {/* 通过类名class控制 */}
            <span className="foo">this is foo</span>
        </div>
    );
}
export default App;
.foo{
    color: yellow;
    font-size: 100px;
}

day2

受控表单绑定

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

image-20240124144505309.png

React中获取dom

import {useRef, useState} from "react";
// 1. useRef生成ref对象 绑定到dom标签身上
// 2. dom可用时, ref.current获取dom
// 渲染完毕之后dom生成之后才可用
function App() {
    const inputRef = useRef(null)
    const showDom = () =>{
        console.dir(inputRef.current)
    }
    return (
        <div>
            <input
                type={"text"}
                ref={inputRef}
            ></input>
            <button onClick={showDom}>获取DOM</button>
        </div>
    );
}
export default App;

父传子基础实现

//父传子
//1.父组件传递数据 子组件标签身上绑定属性
//2.子组件接收数据 props的参数
function Son(props) {
    //props:对象里面包含了父组件传递过来的所有数据
    console.log(props)
    return <div> this is son  {props.content} </div>
}
function App() {
    const name = 'this is father'
    return (
        <div>
           <Son content={name}/>
        </div>
    );
}
export default App;

说明

  1. props可以传递任意的数据

    数字、字符串、布尔值、数组、对象、函数、JSX

    <Son
        content={name}
        age={20}
        isTrue={false}
        list={['Vue','React']}
        obj={{name:'jack'}}
        cb={()=>console.log(123)}
        child={<span>this is a span child</span>}
    />
    
  2. props是只读对象

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

特殊的props children

function Son(props) {
    //props:对象里面包含了父组件传递过来的所有数据
    console.log(props)
    return <div>this is son {props.children}</div>
}
function App() {
    return (
        <div>
            <Son>
                <span>this is span</span>
            </Son>

        </div>
    );
}
export default App;

子传父

import {useState} from "react";

function Son({onGetSonMsg}) {
    const sonMsg = "this is son msg"
    return <div>
        this is son
        <button onClick={()=> onGetSonMsg(sonMsg)}>sendMsg</button>
    </div>
}

function App() {
    const [msg,setMsg] = useState('')
    const getMsg = (msg) => {
        setMsg(msg)
    }
    return (
        <div>
            this is app {msg}
            <Son onGetSonMsg={getMsg}>

            </Son>

        </div>
    );
}

export default App;

使用状态提升实现兄弟组件通信

先把子组件A的内容给父组件app(子传父),再把父组件app获取的A的内容传给子组件B(父传子)

import {useState} from "react";

function A({onGetAName}) {
    const name = "this is son msg"
    return <div>
        this is A
        <button onClick={()=> onGetAName(name)} >sendMsg</button>
    </div>
}
function B({name}) {

    return <div>
        this is B  {name}
    </div>
}
function App() {
    const [AName,setAName] = useState()
    const getAName = (name) =>{
        console.log(name)
        setAName(name)
    }
    return (
        <div>
            this is app {AName}
            <A onGetAName={getAName}/>
            <B name={AName}/>
        </div>
    );
}

export default App;

使用context机制跨层组件通信

实现步骤

  1. 使用createContext方法创建一个上下文对象Ctx
  2. 在顶层组件(App)中通过Ctx.Provider组件提供数据
  3. 在底层组件(B)中通过useContext钩子函数获取消费数据

image-20240124164208755.png

import {createContext, useContext} from "react";

const msgContext = createContext(undefined)
function A() {
    return <div>
        this is a
        <B/>

    </div>
}
function B() {
    const msg = useContext(msgContext)
    return <div>
        this is B  {msg+'111'}
    </div>
}
function App() {
    const msg = 'this is app msg'
    return (
        <div>
            <msgContext.Provider value={msg}>
                this is app
                <A />
            </msgContext.Provider>
        </div>
    );
}

export default App;

useEffect的使用

相当于vue的生命周期函数(mounted、onmounted 等等)

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

image-20240124200514027.png

说明:上面的组件中没有发生任何的用户事件,组件渲染完毕之后就需要和服务器要数据,整个过程属于"只由渲染引起的操作"

useEffect依赖项参数说明(即[])

image-20240124200702288.png

没有依赖项(无论什么变化都执行)

function App() {
    const [count,setCount] = useState(0)
    useEffect(() => {
        console.log('副作用执行!!')
    })
    return (
        <div>
            <button onClick={()=>setCount(count+1)}>{count}</button>
        </div>
    );
}

image-20240124201309981.png

空数依赖项(只有第一次渲染的时候执行)

function App() {
    const [count,setCount] = useState(0)
    useEffect(() => {
        console.log('副作用执行!!')
    },[])
    return (
        <div>
            <button onClick={()=>setCount(count+1)}>{count}</button>
        </div>
    );
}

image-20240124201433612.png

添加特定依赖项(案例只要有count发生变化才执行)

function App() {
    const [count,setCount] = useState(0)
    useEffect(() => {
        console.log('副作用执行!!')
    },[count])
    return (
        <div>
            <button onClick={()=>setCount(count+1)}>{count}</button>
        </div>
    );
}

image-20240124201652590.png

清除副作用

最常见的清楚时期是在组件卸载时自动执行

import {useEffect, useState} from "react";

function Son(){
    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函数

当组件耦合在一起不方便复用时

  1. 声明一个use开头的函数
  2. 在函数体内封装可复用的逻辑
  3. 把组件中用到的状态或者回调return出去
  4. 在哪个组件中要用到这个逻辑,就执行这个函数,结构出来的状态和回调进行使用
function useToggle() {
    const [value, setValue] = useState(true)
    const toggle = () => setValue(!value)
    return {
        value,toggle
    }
}
function App() {
    const {value,toggle} = useToggle();
    return (
        <div>
            {value && <div>this is div</div>}
            <button onClick={toggle}>toggle</button>
        </div>
    );
}

使用规则

  1. 只能在组件中或者其他自定义Hook函数中调用
  2. 只能在组件的顶层调用,不能嵌套在if、for和其他函数中