react18

使用create-react-app快速搭建开发环境

执行命令: npx create-react-app react-basic

1. npx Node.js工具命令,查找并执行后续的包命令

2. create-react-app 核心包(固定写法),用于创建React项目

3. react-basic React项目的名称(可以自定义)

创建React项目的更多方式 https://zh-hans.react.dev/learn/start-a-new-react-project

JSX基础-概念和本质

概念:JSX是JavaScript和XML(HTML)的缩写,表示在JS代码中编写HTML模版结构,它是React中编写 UI模版的方式

 jsx语法

        1:定义虚拟DOM时 不要写引号

        2:标签中混入js表达式要用{}

        3:样式的类名指定不要用class,要用className

        4:内联样式要用style={{key:value}} 的形式去写

        5:只有一个根标签

        6:标签必须是闭合的

        7:标签首字母:

        (1):小写首字母,转为html的同名元素,html没有对应标签报错<good></good>

        (2):大写首字母,react就去找对应组件渲染,没有定义组件则报错<Good></Goo


function App() {
  const list = [1, 2, 3, 4, 5];
  const flag = true;
  const show1 = (e) => {
    console.log(e);
  };
  const show2 = (e, val) => {
    console.log(val);
    console.log(e);
  };
  const show3 = (val) => {
    return (e) => {
      console.log(val);
      console.log(e);
    }
  };
  return (
    <div className="App">
      <header className="app">
        {list.map((item) => {
          return <li key={item}>{item}</li>;
        })
        }
        {flag && <p>Hello World</p>}
        {flag ? <p>Hello World</p> : <p>Hello World</p>}
        <button onClick={show1}>绑定事件没有参数</button>
        <button onClick={(e) => show2(e, 'zs')}>绑定事件传递参数1</button>
        <button onClick={show3('ls')}>绑定事件传递参数2</button>
      </header>
    </div>
  );
}
export default App;

hook 

useState

import { useState } from 'react';
function HookUseState() {
  const [num, setNum] = useState(10);
  {
    /*
    1. useState是一个函数,返回值是一个数组
    2. 数组中的第一个参数是状态变量,第二个参数是set函数用来修改状态变量
    3. useState的参数将作为count的初始值
    */
  }
  const setNumber = () => {
    // num++ //无视图变化
    setNum(num + 1)
  }
  const [person, setPerson] = useState({
    name: 'zs',
    age: 18
  })
  const setPer = () => {
    // person.name = 'ls' //无视图变化
    setPerson({
      name: 'ls',
      age: 20
    })
  }
  return (
    <div>
      <button onClick={setNumber}>useState: {num}</button>
      <button onClick={setPer}>useState对象: {person.name},{person.age}</button>
    </div>
  );
}

export default HookUseState;

useContext 

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

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

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

import { createContext,useContext } from 'react';
const MyContext = createContext()

function HookUseContext() {
  // 跨级通信
  const msg = '我叫张三'
  return (
    <div>
      <MyContext.Provider value={msg}>
        <div>HookUseContext</div>
        <Ason></Ason>
      </MyContext.Provider>
    </div>
  );
}
function Ason() {
  // 跨级通信
  const msg =  useContext(MyContext)
  return (
    <div>
      <div>A:{msg}</div>
      <Bson></Bson>
    </div>
  );
}
function Bson() {
  // 跨级通信
  const msg =  useContext(MyContext)

  return (
    <div>B:{msg}</div>
  );
}
export default HookUseContext;

useEffect

useEffect(()=>{},[])

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

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

import { useState, useEffect } from 'react';
const URL = 'http://geek.itheima.net/v1_0/channels'

function HookUseEffect() {
  const [list, setList] = useState([])
  let [count, setCount] = useState(1)
  let timer = null
  useEffect(() => { //没有依赖 初始渲染执行一次 和 任何数据组件更新时执行
    console.log(111);
  })
  useEffect(() => {//初始渲染只执行一次
    console.log(222);

    timer = setInterval(() => {
      console.log('定时器');
    }, 1000)

    async function getList() {
      const res = await fetch(URL)
      const { data } = await res.json()
      setList(data.channels)
    }
    getList()
  }, [])
  useEffect(() => { //初始渲染执行一次 或 特定依赖更新时执行
    console.log(333);
  }, [count])
  useEffect(() => { //卸载时执行
    return () => {
      console.log(444);
      clearInterval(timer)
    }
  }, [])

  const setN = () => {
    setCount(count + 1)
  }

  return (

    <div>
      <h1>useEffect使用</h1>
      {
        list.map((item) => <div key={item.id}>{item.name}</div>)
      }
      <div>{count}
        <button onClick={setN}>count++</button>
        <button onClick={setN}>定时</button>
      </div>
    </div>
  );
}

export default HookUseEffect;

useMemo 

const monthGroup =useMemo(() => { //类似计算属性
    return _.groupBy(billList,(item)=>dayjs(item.date).format('YYYY-MM') )
  }, [billList])
 const monthResult = useMemo(() => {
    const  pay = currentMonthList.filter(item => item.type === 'pay').reduce( (acc,cur) => acc + cur.money,0)
    const  income = currentMonthList.filter(item => item.type === 'income').reduce( (acc,cur) => acc + cur.money,0)
    return {pay,income,total:pay +income}
  },[currentMonthList])

useLocation

  // 1. 获取当前路由路径
  const location = useLocation()
  console.log(location.pathname)

自定义hook

import { useState } from "react";
  /*
  封装自定义hook通用思路
  1.声明一个以use打头的函数
  2.在函数体内封装可复用的逻辑(只要是可复用的逻辑)
  3.把组件中用到的状态或者回调return出去(以对象或者数组)
  4、在哪个组件中要用到这个逻辑,就执行这个函数,解构出来状态和回调进行使用I
  */
function useToggle() {
  const [flag, setFlag] = useState(true)
  const toggleShow = () => {
    setFlag(!flag)
  }
  return { flag, toggleShow }//其他组件要用就return
}

function MyHook() {
  // 自定义显示隐藏的hook基本分析
  // const [flag, setFlag] = useState(true)
  // const toggleShow = () => {
  //   setFlag(!flag)
  // }
  const { flag, toggleShow } = useToggle()
  return (
    <div>
      {flag && <h1>自定义hook</h1>}
      <button onClick={toggleShow}>toggle</button>
    </div>
  );
}

export default MyHook;

总结HOOK的使用规则 

动态样式className

 <div className={`cur ${id == xxx.id && 'active'}`}></div> 动态样式和多个样式

排序通过lodash

classNames优化类名管理 

npm i classnames

import classNames from 'classname'

className={classNames('cur',{active: id == xxx.id})}

cur是静态类名 active是动态类名

表单控件 

 handleSubmit = (event) => {
   event.preventDefault();
   const {username, password} = this
   alert(`用户名:${username.value}密码:${password.value}`)
}
<form action="http://www.atguigu.com" onSubmit={this.handleSubmit}>
   用户名:<input ref={c=>this.username = c} type="text" name='username'/>
   密码:<input  ref={c=>this.password = c} type="text" name='password'/>
   <button>登录</button>
</form>
state = {
                username: 'qwe',
                password: '123'
            }
            handleSubmit = (event) => {
                event.preventDefault();
                const { username, password } = this.state
                alert(`用户名:${username}密码:${password}`)
            }
            saveUsername = (event) => {
                // console.log(event.target.value);
                this.setState({ username: event.target.value })
            }
            savePassword = (event) => {
                // console.log(event.target.value);
                this.setState({ password: event.target.value })
            }
            render() {
                return (
                    <form action="http://www.atguigu.com" onSubmit={this.handleSubmit}>
                        用户名:<input onChange={this.saveUsername} value={this.state.username} type="text" name='username' />
                        密码:<input onChange={this.savePassword} value={this.state.password} type="text" name='password' />
                        <button>登录</button>
                    </form>
                )
            }
        }

 

ref

 <script type="text/babel">//用的jsx要写text/babel
    class Person extends React.Component {
      showData = () => {
        const { input1 } = this.refs
        alert(input1.value)
      }
      showData1 = () => {
        const { input2 } = this.refs
        alert(input2.value)
      }
      // ref是字符串( 不推荐 )
      render() {
        return (
          <div>
            <input ref="input1" type="text" placeholder="点我提示" />
            <button onClick={this.showData}>点我</button>
            <input ref="input2" onBlur={this.showData1} type="text" placeholder="失去焦点提示" />
          </div>
        )
      }
    }
    // 渲染到组件到页面
    // 需求1在页面上展示的年龄都大一岁
    // 在传递数据时,传递数字年龄age={18} 字符串数字age="20"
    ReactDOM.render(<Person />, document.getElementById('test1'))
  </script>
 <script type="text/babel">//用的jsx要写text/babel
        class Person extends React.Component {
            // 推键
            myRef1 = React.createRef()//调用放回一个容器 可以存储被ref标识的节点(一人一个专人专用)
            myRef2 = React.createRef()//调用放回一个容器 可以存储被ref标识的节点
            showData = () => {
                alert(this.myRef1.current.value)
            }
            showData1 = () => {
                alert(this.myRef2.current.value)
            }
            // ref是字符串( 不推荐 )
            render() {
                return (
                    <div>
                        <input ref={this.myRef1} type="text" placeholder="点我提示" />
                        <button onClick={this.showData}>点我</button>
                        <input ref={this.myRef2} onBlur={this.showData1} type="text" placeholder="失去焦点提示" />
                    </div>
                )
            }
        }

        // 渲染到组件到页面
        // 需求1在页面上展示的年龄都大一岁
        // 在传递数据时,传递数字年龄age={18} 字符串数字age="20"
        ReactDOM.render(<Person />, document.getElementById('test1'))

    </script>
  <script type="text/babel">//用的jsx要写text/babel
        class Person extends React.Component {
            showData=()=>{
                const { input1 } = this
                alert(input1.value)
            }
            showData1=()=>{
                const { input2 } = this
                alert(input2.value)
            }
                        // ref是字符串( 不推荐 有效率上的问题 )
                        // currentNode 就是<input type="text" placeholder="点我提示"/>

            render() {
                return (
                    <div>
                        <input ref={(currentNode)=>{this.input1 = currentNode}} type="text" placeholder="点我提示"/>
                        <button onClick={this.showData}>点我</button>
                        <input ref={(currentNode)=>{ this.input2= currentNode}} onBlur={this.showData1} type="text" placeholder="失去焦点提示"/>
                    </div>
                )
            }
        }

        // 渲染到组件到页面
        // 需求1在页面上展示的年龄都大一岁
        // 在传递数据时,传递数字年龄age={18} 字符串数字age="20"
        ReactDOM.render(<Person/>, document.getElementById('test1'))
        
    </script>
    <script type="text/babel">//用的jsx要写text/babel
        const App =( props) => {
            console.log(props);
            const inputRef = React.useRef(null)
            const btn = React.createRef()
            const [n, setN] = React.useState(0)
            function addNum() {
                setN(n+1)
                console.log(inputRef.current.value);
                console.log(btn.current);
            }
            return (
                <div className='App'>
                    <input ref={inputRef} />
                    {n}
                    <button ref={btn} onClick={addNum}>+1</button>
                </div>
            )
        }

        // 渲染到组件到页面
        ReactDOM.render(<App name='zs'/>, document.getElementById('test'))
    </script>

插件

日期插件 : dayjs

随机id插件 : uuid

props 

function PropsAndMore() {
  const getData = (data) => {
    console.log(data);
  };
  return (
    <div>
      <Son name={'zs'} age={19} getData={getData}>
        <span>solt</span>
      </Son>
    </div>
  );
}

function Son(prop) {
  console.log(prop);
  const { name, age } = prop;
  const toData = () => {
    // 父组件调用子组件方法
    prop.getData('son');
  };
  return (
    <div>
      <h1>son</h1>
      {name}-{age}-{prop.children}
      <button onClick={toData}>getData</button>
    </div>
  );
}
export default PropsAndMore;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值