当前位置:   article > 正文

React18——setState变成异步——suspence组件懒加载结合异步数的传递_react18 setstate

react18 setstate

带来什么

  • 改进已有属性,如自动批量处理【setState】、改进Suspense、组件返回undefined不再报错等、
  • 支持Concurrent(批处理)模式,带来新的API,如useTransition、useDeferredValue等
  • 注:React升级对于开发者而言,无需重写代码就能够使用React18
  • react18.2新特性——性能更高。
    Suspense:支持批处理,setState变成异步
    并发处理

使用脚手架

yarn create react-app myapp
  • 1

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')
// )

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在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;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

我非要操作这个同步的数据
flushSync

// flushSync它方法就可以让里面的操作为同步
import { flushSync } from 'react-dom'
flushSync(()=>{
    this.setState(v=>({num:++v.num}))
})
因为setState放在flushSync方法里面了,则它现在是一个同步的,所以在此处可以得到最新的数据
console.log(this.state.num);//得到同步
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

条件渲染异步数据传给子组件

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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

以前是条件渲染异步数据给子组件;

{/* 条件渲染 */}
{data.length == 0 ? <div>加载中...</div> : <About data={data}></About>}   
  • 1
  • 2

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);
    })
},[])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

通过函数直接初始化得到数据:
解析promise
相关此函数的使用链接为:
http://t.csdn.cn/UwHA9
解析promise

let [data,setData] = useState(midderPromise(fentchMsg()));
//经过测试暂时有个bug,只支持子组件的使用;
  • 1
  • 2

<Suspense fallback={<h3>加载中。。。。</h3>}>
    <Home></Home>
    <hr />
    {/* 异步数据渲染 */}
    <About data={data}></About>
</Suspense>          
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/383466
推荐阅读
相关标签
  

闽ICP备14008679号