JSX将HTML语法直接加入到JS代码中,在通过翻译器转换到纯js后由浏览器执行,实际开发中,JSX在产品打包阶段已经编译为js,无副作用,让代码易于维护更加直观,编译过程由Babel的JSX编译器实现。
import React from 'react'
import Child from './components/Child'
export default class Demo extends React.Component{
state={
info:{} //传递给子组件
}
saveList(list){
//子组件传来的数据
console.log(list)
}
render(){
}
}
import logo from './logo.svg';
import './App.css';
function App() {
return (
Edit src/App.js
and save to reload.
Learn React
);
}
export default App;
高阶组件为了复用,导致代码层级复杂,生命周期复杂,写成function组件,无状态组件,写成class类组件,成本过高,我们可以使用react hooks
const [state,setState] = useState(inintialState)
示例:
import { useState } from 'react';
function App() {
const [name, setName] = useState('张三')
const [text, setText] = useState('')
const [list, setList] = useState([])
const [age, setAge] = useState(88)
function addList() {
setList([...list, text])
setText('')
}
function handleChange(e) {
setText(e.target.value)
}
function handleDelete(index) {
console.log(index);
let arr = [...list]
arr.splice(index, 1)
console.log(arr);
setList(arr)
}
return (
app-{name}
app-{age}
handleChange(e)} value={text} />
{
list.map((el, index) => {
return - {el}
})
}
{!list.length && 暂无事项}
);
}
export default App;
第二个参数为空数组时,此函数只执行一次,相当于 componentDidMount 生命周期函数
import { useState,useEffect } from 'react';
function App() {
const [list, setList] = useState([])
useEffect(()=>{
setList([11])
},[])
return (
{
list.map((el, index) => {
return - {el}
})
}
);
}
export default App;
第二个参数传入参数时,此函数会监听该参数的变化,且再次执行该函数,相当于 componentDidUpdate 生命周期函数
import { useState,useEffect } from 'react';
function App(props) {
const [name, setName] = useState("apple")
useEffect(()=>{
setName(name.toUpperCase())
},[name])
return (
app-{name}
);
}
export default App;
useEffect和useLayoutEffect用法基本一致,唯一不同点就是调用时机不同,useLayoutEffect和原来 componentDidMount componentDidUpdate一致,react完成dom后马上同步调用的代码,会阻塞页面渲染,useEffect会再页面渲染完成后才调用。
防止因为组件重新渲染,导致方法被重新创建,起到缓存作用,只有第二个参数发生变化了,才重新声明一次。(因为每次调用useState中的set函数就会触发组件渲染)
在函数内用到的所有变量,需要写在第二个参数数组中,可以监听到变化渲染师重新生成新的函数,如果不写,那么永远都是不会重新生成新的函数,并且使用到的变量值都是旧的,不会更新。
import { useState, useEffect, useCallback } from 'react';
function App() {
let [name, setname] = useState(0)
const handleChange = useCallback(() => {
setname(name + 1);
}, [name])
return (
app-{name}
);
}
export default App;
useCallback的功能完全可以由useMemo所取代,如果你想通过使用useMemo返回一个记忆函数也是完全可以的。
useCallback(fn,inputs)
useMemo(()=>fn,inputs)
唯一区别是:useCallback不会执行第一个参数函数,而是将它返回给你,而useMemo会执行第一个函数并且将函数执行结果返回给你。
所以useCallback常用于记忆事件函数,生成级以后得事件传给子组件使用;而useMemo更适合经过函数计算得到一个确定的值,比如记忆组件。类似于vue中的computed计算属性
import { useState, useEffect, useCallback, useMemo } from 'react';
function App() {
let [name, setname] = useState(0)
const name2 = useMemo(() => name+1000, [name])
const handleChange = useCallback(() => {
setname(name + 1);
}, [name])
return (
app-{name}
{name2}
);
}
export default App;
1.能够用来定位元素或者组件
2.能够存储变量
import { useRef, useState } from 'react';
function App() {
let [count,setCount] = useState(0)
const myName = useRef()
const myCount = useRef(0)
return (
app
{myCount.current}
);
}
export default App;
import React,{useContext, useState, createContext} from 'react';
const CountContext = createContext();//创建Context对象
const TestContext = () =>{
const [count, setCount] = useState(0);
console.log(CountContext);
console.log(useContext(CountContext));
return(
父组件点击次数:{count}
)
};
const Counter = () => {
const count = useContext(CountContext);
console.log(CountContext);
// console.log(count);
// console.log(useContext(CountContext));
return (
子组件获得的点击数量:{count}
);
};
export default TestContext;
redux的钩子函数,状态数据管理,可以在APP.js中定义一次,在其他组件中传入state, dispatch,进行调用
import { useReducer } from 'react';
//处理函数
const reducer = (preState, action) => {
let newState = {...preState}
switch (action.type) {
case 'add':
newState.count++
return newState
case 'minus':
newState.count--
return newState
default:
return preState
}
}
const initialState = {
count: 0
}
function App() {
const [state, dispatch] = useReducer(reducer, initialState)
return (
{state.count}
);
}
export default App;
可搭配useContext使用
import { useReducer, createContext, useContext } from 'react';
//处理函数
const reducer = (preState, action) => {
let newState = { ...preState }
switch (action.type) {
case 'add':
newState.count++
return newState
case 'minus':
newState.count--
return newState
default:
return preState
}
}
const initialState = {
count: 0
}
const CountContext = createContext()
function App() {
const [state, dispatch] = useReducer(reducer, initialState)
return (
);
}
function Child1() {
const obj = useContext(CountContext)
return child1-{obj.state.count}
}
function Child2() {
const obj = useContext(CountContext)
return
child1-{obj.state.count}
}
export default App;
useId
是一个 React Hook,可以生成传递给无障碍属性的唯一 ID。
const id = useId()
自定义hooks
当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中
必须以 use 开头,如不遵循,由于无法判断某个函数是否包含对其内部hook的调用,React将无法自动检查你的hook是否违反了hook规则,与vue3中自定义组合式api用法相同。
import { useState,useEffect } from 'react';
function useList(){
const [list, setList] = useState([])
useEffect(()=>{
setList([11])
},[])
return{
list
}
}
function App() {
const {list} = useList()
return (
{
list.map((el, index) => {
return - {el}
})
}
);
}
export default App;