赞
踩
注意:React升级对于开发者而言,无需重写代码就能够使用React18
用以下几种方案创建出来的项目使用为react18版本:
npx create-react-app myapp
npm init react-app myapp
yarn create react-app myapp
注意:
- nodejs版本一定要为16.x及以上版本,如果你用的是win笔记本,则操作系统不能低于win10
- react18中的webpack版本为5版本
import React from 'react' // react18它引入ReactDOM类的位置发生改变 import ReactDOM from 'react-dom/client' // 在react18之后,不要用此方案来引入ReactDOM类 // import ReactDOM from 'react-dom' import App from './App' // 把虚拟dom挂载到真实dom中的方法也发生了改变 由原来的render方法,变为 createRoot(dom节点).render(<App/>) // 支持Concurrent模式[批处理,让setState都为异步] -- 提升性能 const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> ); // 也可以使用 React17 中的方案 // 不支持Concurrent模式,所以在react18之后就不要写此方案 // ReactDOM.render( // <React.StrictMode> // <App /> // </React.StrictMode>, // document.getElementById('root') // )
在 react18 之后,setState 都为异步,无论写在什么样的语法环境中。
import React, { Component } from 'react' class App extends Component { state = { count: 100 } addCount = () => { // 异步的,写成回调函数的方式,可以获得最新的数据状态 this.setState( state => ({ count: state.count + 1 }), () => console.log(this.state.count) ) // 此方案在react18之前,它里面的操作是同步的,但在react18之后,它都为concurrent模式,都为异步 // setTimeout(() => { // this.setState(state => ({ count: state.count + 1 })) // console.log(this.state.count) // }, 1) } render() { return ( <div> <h3>{this.state.count}</h3> <button onClick={this.addCount}>累加count</button> </div> ) } } export default App
如果在 react18 中,我们想要让 setState 变为同步,我们可以使用 flushSync 方法:
import React, { Component } from 'react' // flushSync它方法就可以让里面的操作为同步 import { flushSync } from 'react-dom' class App extends Component { state = { count: 100 } addCount = () => { // react18中,就想让setState它为同步【可以,但不要在生产中去用,不建议】 // setState它就是同步的 flushSync(() => { this.setState(state => ({ count: state.count + 1 })) }) // 因为setState放在flushSync方法里面了,则它现在是一个同步的,所以在此处可以得到最新的数据 console.log(this.state.count) } render() { return ( <div> <h3>{this.state.count}</h3> <button onClick={this.addCount}>累加count</button> </div> ) } } export default App
mock 数据:
[
{ "id": 1, "name": "张三" },
{ "id": 2, "name": "英子" },
{ "id": 3, "name": "乐乐" }
]
父组件:
import React, { useEffect, useState } from 'react' import User from './pages/User' const fetchUser = async () => { let ret = await (await fetch('/users.json')).json() return ret } const App = () => { let [data, setData] = useState([]) useEffect(() => { fetchUser().then(ret => setData(ret)) }, []) return ( <div> {/* 条件渲染 */} {data.length == 0 ? <div>加载中...</div> : <User data={data} />} </div> ) } export default App
子组件:
import React from 'react' const User = ({ data }) => { return ( <div> <ul> {data.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ) } export default User
父组件:
import React, { Suspense, useEffect, useState } from 'react' import User from './pages/User' // 网络请求 // 返回值为 Promise const fetchUser = async () => { let ret = await (await fetch('/users.json')).json() return ret } // 创建一个用于解析promise中数据的方法 仿promise的3个状态 const wrapperPromise = promise => { // 定义一个promise的状态 let status = 'pending' // 它就是promise解析出来的数据接受的变量 let result const callbackPromise = promise.then( ret => { // promise执行成功的,返回成功的状态,并把数据赋值给result status = 'success' result = ret }, err => { // 把状态修改为失败,并把错误赋值给result status = 'error' result = err } ) return { // 此方法中,才是把数据获取到 read() { if (status === 'pending') { // 抛一个异常,这样它就会再来执行,此时就会有上一次的结果 throw callbackPromise } else if (status === 'success') { return result } else if (status === 'error') { return result } } } } const App = () => { let [data, setData] = useState(wrapperPromise(fetchUser())) return ( <div> <Suspense fallback={<div>加载中 .......................................</div>}> <User users={data} /> </Suspense> </div> ) } export default App
子组件:
import React from 'react' // 函数组件,它需要返回jsx而不是一个promise对象 const User = ({ users }) => { // 通过此方法把promise中的数据读取出来 let data = users.read() return ( <div> <ul> {data.map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ) } export default User
概述:
如果你有很多没那么着急的内容要渲染更新就可以使用此hook函数。它可以对于更新渲染进行降级,提高更重要的组件的提前渲染
使用:
import React, { useState, useTransition } from 'react' // 可以对于更新渲染进行降级,提高更重要的组件的提前渲染 const App = () => { let [count, setCount] = useState(100) // isPending 如果在更新等待渲染时isPending为true,没有等待更新不渲染时为false // startTransition 它是一个函数,在里面写的更新数据会进行降级 let [isPending, startTransition] = useTransition() const addCount = () => { // 对于更新count的数据时行了降级,更新也就会降级 startTransition(() => { setCount(v => v + 1) }) } return ( <div> {/* count更新它没有哪么的着急,可以让别的数据更新渲染先执行 */} <h3>{isPending ? '加载中...' : count}</h3> <button onClick={addCount}>++++++</button> </div> ) } export default App
概述:
该方法使得我们可以延迟更新某个不那么重要的部分,有节流防抖效果。可以将原来的更新进行推迟渲染,把重要的更新数据推到前面去更新渲染去。
使用:
父组件:
import React, { useState, useDeferredValue } from 'react' import Search from './pages/Search' const App = () => { let [kw, setKw] = useState('') // 让数据更新降级,起到了节流的效果,让渲染平滑一些 let deferredValue = useDeferredValue(kw) return ( <div> <h3>{kw}</h3> <input value={kw} onChange={e => setKw(e.target.value.trim())} /> <Search kw={deferredValue} /> </div> ) } export default App
子组件:
import React from 'react' const Search = ({ kw }) => { console.log(kw) const data = Array(1000) .fill('') .map((_, index) => { return '搜索 -- ' + index + ' -- ' + kw }) return ( <div> <ul> {data.map(item => ( <li key={item}>{item}</li> ))} </ul> </div> ) } export default Search
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。