React18——setState变成异步——suspence组件懒加载结合异步数的传递
Posted 勇敢*牛牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React18——setState变成异步——suspence组件懒加载结合异步数的传递相关的知识,希望对你有一定的参考价值。
带来什么
- 改进已有属性,如自动批量处理【setState】、改进Suspense、组件返回undefined不再报错等、
- 支持Concurrent(批处理)模式,带来新的API,如useTransition、useDeferredValue等
- 注:React升级对于开发者而言,无需重写代码就能够使用React18
- react18.2新特性——性能更高。
Suspense:支持批处理,setState变成异步
并发处理
使用脚手架:
yarn create react-app myapp
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'
// 路由
import BrowserRouter as Router from 'react-router-dom'
// redux
import Provider from 'react-redux'
// import store from './redux'
import store from './store'
// 把虚拟dom挂载到真实dom中的方法也发生了改变 由原来的render方法,变为 createRoot(dom节点).render(<App/>)
// 支持Concurrent模式[批处理,让setState都为异步] -- 提升性能
ReactDOM.createRoot(document.getElementById('root')).render(
<Provider store=store>
<Router>
<App />
</Router>
</Provider>
)
// 不支持Concurrent模式,所以在react18之后就不要写此方案
// ReactDOM.render(
// <React.StrictMode>
// <App />
// </React.StrictMode>,
// document.getElementById('root')
// )
在react18之后,setState都为异步,无论写在什么样的语法环境中
setState无论写在哪里都是变成异步处理
import React, Component from 'react';
class App extends Component
state =
num:100
count = ()=>
this.setState(v=>(num:++v.num),()=>
console.log("异步处理,同步体现",this.state.num);//同步
);
console.log("同步处理,异步体现",this.state.num);//异步
setTimeout(()=>
console.log("异步数据,异步体现",this.state.num);//异步
)
//此方案在react18之前,它里面的操作是同步的,但在react18之后,它都为concurrent模式,都为异步
setTimeout(()=>
this.setState(v=>(num:++v.num))
console.log("别费力气,还是异步体现",this.state.num);//异步
)
render()
return (
<div>
<h1>this.state.num</h1>
<button onClick=this.count>+++</button>
</div>
);
export default App;
我非要操作这个同步的数据
flushSync
// flushSync它方法就可以让里面的操作为同步
import flushSync from 'react-dom'
flushSync(()=>
this.setState(v=>(num:++v.num))
)
因为setState放在flushSync方法里面了,则它现在是一个同步的,所以在此处可以得到最新的数据
console.log(this.state.num);//得到同步
条件渲染异步数据传给子组件
Suspense组件懒加载
import React,lazy,Suspense from 'react';
const Home = lazy(()=>import(/* webpackChunkNameHome */"./views/Home"));
const About = lazy(()=>import(/* webpackChunkNameAbout */"./views/About"));
const App = () =>
return (
<div>
<Suspense fallback=<h3>加载中。。。。</h3>>
<Home></Home>
<hr />
<About></About>
</Suspense>
</div>
);
export default App;
以前是条件渲染异步数据给子组件;
/* 条件渲染 */
data.length == 0 ? <div>加载中...</div> : <About data=data></About>
Suspense结合异步数据组件实现条件渲染
如何在其他函数中获取异步的数据,异步函数的返回值是一个Promise,需要通过实例对象的方法.then来获取
原阿里的写法
let [data,setData] = useState([]);
const fentchMsg = async ()=>
let users = await (await fetch("mock/users.json")).json();
return users;
//promise的使用
useEffect(()=>
fentchMsg().then(ret=>
console.log(ret);
setData(ret);
)
,[])
通过函数直接初始化得到数据:
解析promise
相关此函数的使用链接为:
http://t.csdn.cn/UwHA9
解析promise
let [data,setData] = useState(midderPromise(fentchMsg()));
//经过测试暂时有个bug,只支持子组件的使用;
<Suspense fallback=<h3>加载中。。。。</h3>>
<Home></Home>
<hr />
/* 异步数据渲染 */
<About data=data></About>
</Suspense>
以上是关于React18——setState变成异步——suspence组件懒加载结合异步数的传递的主要内容,如果未能解决你的问题,请参考以下文章