学习笔记——React18

123 阅读5分钟

前言

没有学习过react的其他版本,这次仅仅是针对react18上的开发方式做一个笔记,归纳总结

起步

  1. 直接上react的脚手架,my-app是你的项目名,这里有好几种创建react脚手架的命令,这里我选的是第一种,也是react官网建议用于学习用途的一种。另外几种创建方式有它自己的优势,详情可以阅读官网。
1.npx create-react-app my-app
2.npx create-next-app
3.npx create-remix
4.npx create-gatsby
5.npx create-expo-app
  1. 项目初始化后的文件

和vue对比的话,其实大差不差,有一些学习时候用不着的文件,删除后,就剩下index.js这个入口文件,和app.js这个ui文件了,然后将app.js改成app.jsx,这样可以更好的支持jsx语法。

用函数式组件编写react代码

1. 函数式组件写法

开始学习react的写法前,react是有类组件和函数式组件的写法差异的,在官网上目前都是推荐函数式写法,所以这次学习笔记并没有记录类组件的写法。

你可以声明任意一个函数,函数命名需要以大写字母开头(规范),该函数最后return的是一段jsx模板。这个便是一个函数式的组件,并将该函数导出。

注意,返回的jsx中,必须要有一个根节点包裹着,可以用空的根节点包裹<></>

function App () {
  return (
    <div>
      Hello,word
    </div>
  );
}
export default App;

绑定方法和用useState声明数据

1. 绑定方法

  • react中,在jsx中使用动态的数据或者方法,我们需要在对应的位置用一对大括号将变量给包裹起来{}。
function App () {
  let num = 0
  const handleClickAdd = ()=>{
    num++
    console.log(num)
  }
  return (
    <div>
      <div>当前num值:{num}</div>
      <button onClick={handleClickAdd}>点我+1</button>
    </div>
  );
}
export default App;

2. hook-useState声明数据

  • react中,如果我们想要通过改变数据,视图也同步改变的话,我们需要使用useState这个api。它接受一个初始的值,可以是数字,字符,对象,数组等。该函数返回的是一个2位长度的数组,第一位是该变量的名称,第二位则是用于修改对应变量的方法。我们需要在修改对应的数据时,通过解构出来的set方法去修改该数据,此时,页面就会跟着重新渲染。
import { useState } from 'react'; //导入对应的api
function App () {
  let [num, setNum] = useState(0) //解构出变量和设置变量的方法
  const handleClickAdd = () => {
    setNum(num + 1)
    console.log(num)
  }
  return (
    <div>
      <div>当前num值:{num}</div>
      <button onClick={handleClickAdd}>点我+1</button>
    </div>
  );
}
export default App;

3. 函数如何传参

  • 关于函数如何传递参数,这块需要在jsx中对函数进行改写,将原来的函数用箭头函数包裹起来,并进行传参。
import { useState } from 'react'; //导入对应的api
function App () {
  let [num, setNum] = useState(1)
  const handleClickAdd = (perValue) => {
    setNum(num + perValue)
    console.log(num)
  }
  return (
    <div>
      <div>当前num值:{num}</div>
      <button onClick={()=>handleClickAdd(num)}>点我+{num}</button>
    </div>
  );
}
export default App;

4. hook-useState需要注意的

  1. 请勿直接修改state的值,请将state当成只读的,api返回的set方法是将传入的新值覆盖旧值的
  2. 减少state的声明,如要实现 a+b=c,你并不需要将3个变量都声明为state,请仔细考虑需求中哪些变量应该作为state

组件间传值通信

1. 组件间如何嵌套

像写html一样,我们只需要抽象的理解为,在某一个函数组件里,引用了另一个函数组件并返回,那么被引用的函数组件就成为了该函数组件的子组件。

function ImgShowBox () {
  return (
    <img src="" alt="" />
  )
}
function ImgListBox () {
  return (
    <div>
     <ImgShowBox></ImgShowBox> {/* 该组件为子组件 */}
    </div>
  )
}
export default ImgListBox

2. 如何传值给父组件

只需要在子组件中,写上对应传递的名字和变量即可,该值可以是静态的,也可以是动态的

import { useState } from 'react'; //导入对应的api
function ImgShowBox () {
  return (
    <img src="" alt="" />
  )
}
function ImgListBox () {
  let [url,setUrl] = useState("")
  return (
    <div>
      <button>上一张</button>
      <button>下一张</button>
     <ImgShowBox mySrc={url} name="一张图片"></ImgShowBox> {/* 该组件为子组件 */}
    </div>
  )
}
export default ImgListBox

3. 如何接收子组件的值

我们可以通过props来进行父子组件的通信,用法很简单,每一个函数组件都会接收一个props的形参,该形参包含了父组件传递的参数。

\

import { useState } from 'react'; //导入对应的api
//解构赋值获取参数,并设定默认值
function ImgShowBox ({ url = "", name = "" }) {
  return (
    <div>
      <button>不看了</button>
      <img src={src} alt="" />
    </div>

  )
}
function ImgListBox () {
  let [url, setUrl] = useState("")
  return (
    <div>
      <button>上一张</button>
      <button>下一张</button>
      <ImgShowBox mySrc={url} name="一张图片"></ImgShowBox> {/* 该组件为子组件 */}
    </div>
  )
}
export default ImgListBox

4. 如何让子组件更新props的值

我们只需要在父组件中定义好对应更新props的方法,并将该方法通过props传入即可

import { useState } from 'react'; //导入对应的api
//解构赋值获取参数,并设定默认值
function ImgShowBox ({ url = "", name = "",noShowImg}) {
  return (
    <div>
      <button onClick={()=>{noShowImg("不想看了")}}>不想看了</button>
      <img src="" alt="" />
    </div>

  )
}
function ImgListBox () {
  let [url, setUrl] = useState("https://一个图片地址")
  const noShowImg = (value) =>{
    setUrl("")
  }
  return (
    <div>
      <button>上一张</button>
      <button>下一张</button>
      <ImgShowBox mySrc={url} name="一张图片" noShowImg={noShowImg}></ImgShowBox> {/* 该组件为子组件 */}
    </div>
  )
}
export default ImgListBox

5 如何设置props的类型和默认值

使用prop-types插件

条件渲染和循环渲染(类比vue的v-if和v-for)

1. 如何进行条件渲染

这里用了2种不同的写法,一个直接在jsx上判断,一个通过函数调用返回不同的jsx

import { useState } from 'react'; //导入对应的api
function App () {
  let data = [
    { content: "吃饭", complete: false },
    { content: "洗澡", complete: true },
    { content: "刷牙", complete: false },
  ]
  const setIsCompleteDom = (flag) => {
    if (flag) {
      return (
        <span>完成√</span>

      )
    } else {
      return (
        <span>未完成X</span>
      )
    }
  }
  return (
    <div>
      <p>
        <span>待办:{data[0].content}</span>
        {
          setIsCompleteDom(data[0].complete)
        }
      </p>
      <p>
        <span>待办:{data[1].content}</span>
        {data[1].complete ? <span>完成√</span> : <span>未完成X</span>}
      </p>
      <p>
        <span>待办:{data[2].content}</span>
        {data[2].complete ? <span>完成√</span> : <span>未完成X</span>}
      </p>
    </div>
  );
}
export default App;

2. 如何进行循环渲染

归根到底,其实就是我们要通过js的方法,去循环遍历一个数据,组装好一段jsx。我们这里要特别注意,这个key要确保唯一性。

import { useState } from 'react'; //导入对应的api
function App () {
  let data = [
    { content: "吃饭", complete: false },
    { content: "洗澡", complete: true },
    { content: "刷牙", complete: false },
  ]
  const setIsCompleteDom = (flag) => {
    if (flag) {
      return (
        <span>完成√</span>
      )
    } else {
      return (
        <span>未完成X</span>
      )
    }
  }
  const setToDoJSX = () => {
    return data.map(item => {
      return (
        <li key={item.content}>
          <span>{item.content}</span>
          {setIsCompleteDom(item.complete)}
        </li>
      )
    })

  }
  return (
    <div>
      <ul>
        {setToDoJSX()}
      </ul>
    </div>
  );
}
export default App;

redux使用(待更新)