V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
17681880207
V2EX  ›  程序员

React useState 修改值之后,如何获取到最新的值

  •  
  •   17681880207 · 2021-09-03 13:56:38 +08:00 · 2615 次点击
    这是一个创建于 937 天前的主题,其中的信息可能已经有所发展或是发生改变。

    页面上有一个 radio group,点击 radio 按钮之后,重新获取 table 数据。 在 setModule 之后,需要立马重新获取表格数据,但是发现 module 值是老的。

    let [module, setModule] = useState('1')
    
    const changeModule = (e) => {
      setModule(e.target.value)
      getTableData ()
      console.log('module :', module) // 此时,发现 module 的值是老的
    }
    
    const getTableData = async () => {
      const params = {}
      Object.assign(params, {
        moduleId: module
      })
      // 此时的 moduleId 发现是老的值,而不是新点击的值
      const r = await axios.get('/get-table-data', params)
    }
    
    <Radio.Group 
      options={[
        {label: 'option1', value: '1'}, 
        {label: 'option2', value: '2'},
        {label: 'option3', value: '3'},
        {label: 'option4', value: '4'}
      ]}
      value={module} 
      onChange={changeModule}/>
    

    各位大神,应该如何处理?

    24 条回复    2021-09-05 22:18:40 +08:00
    JimmyquSpe
        1
    JimmyquSpe  
       2021-09-03 14:01:27 +08:00 via Android
    settimeout
    17681880207
        2
    17681880207  
    OP
       2021-09-03 14:03:34 +08:00
    @JimmyquSpe 不会吧....
    coolcoffee
        3
    coolcoffee  
       2021-09-03 14:04:28 +08:00
    你如果要基于 module 更新去执行 getTableData, 那么你应该这样做。

    ``` javascript
    useEffect(() => {
    if (module) {
    getTableData();
    }
    }, [module]);
    ```
    johnwood
        4
    johnwood  
       2021-09-03 14:04:32 +08:00
    # 1
    getTableData ( e.target.value )

    #2
    useEffect(()=>{getTableData()},[module])
    X_Del
        5
    X_Del  
       2021-09-03 14:04:56 +08:00
    ```
    useEffect(() => {
    getTableData()
    }, [module]);
    ```
    Leviathann
        7
    Leviathann  
       2021-09-03 14:16:29 +08:00
    改一下 getTableData,把 value 传进去?
    Rocketer
        8
    Rocketer  
       2021-09-03 14:19:04 +08:00 via iPhone
    楼上说的很清楚了,要靠 useEffect 来监控值的变化。

    但你这个情况有点简单,何不直接用 e.target.value ?
    mightofcode
        9
    mightofcode  
       2021-09-03 14:20:06 +08:00
    用 useEffect

    module 不是一个简单的变量,相关操作都要依赖 react 的体系
    lingo
        10
    lingo  
       2021-09-03 15:04:44 +08:00
    这情况 useEffect 应该是最符合 react hook 思想的做法了吧
    towave
        11
    towave  
       2021-09-03 15:18:27 +08:00
    传参最快
    zhaol
        12
    zhaol  
       2021-09-03 15:27:19 +08:00
    react 的 setState 在 js 代码里面表现是异步的,所以你拿的值不是最新的。用 settimeout 可以解决,但是不推荐; react hook 就用 useEffect,class component 就在 setState 的第二个参数做查询;传参也简单,楼上的解决方法都挺好的
    wiluxy
        13
    wiluxy  
       2021-09-03 15:29:27 +08:00
    ~~~js
    let [module, setModule] = useState('1')

    const changeModule = (e) => {
    setModule(e.target.value)
    getTableData ()
    }
    useEffect(()=>{
    console.log('module :', module) // 每次更新 module 后的逻辑写在次,拿到的 module 是最新的
    },[module])

    const getTableData = async () => {
    const params = {}
    Object.assign(params, {
    moduleId: module
    })
    // 此时的 moduleId 发现是老的值,而不是新点击的值
    const r = await axios.get('/get-table-data', params)
    }

    <Radio.Group
    options={[
    {label: 'option1', value: '1'},
    {label: 'option2', value: '2'},
    {label: 'option3', value: '3'},
    {label: 'option4', value: '4'}
    ]}
    value={module}
    onChange={changeModule}/>
    ~~~
    flybears
        14
    flybears  
       2021-09-03 16:08:01 +08:00
    const changeModule = (e) => {
    setModule(e.target.value)
    setModule(e => {})
    }
    flybears
        15
    flybears  
       2021-09-03 16:09:02 +08:00
    const changeModule = (e) => {
    setModule(e.target.value)
    setModule(value => {
    //这个是修改之后的值
    console.log(value)
    })
    }
    flybluewolf
        16
    flybluewolf  
       2021-09-03 16:19:29 +08:00
    哎,回复没一个对的。useReducer 啊,多看官方文档啊
    Puteulanus
        17
    Puteulanus  
       2021-09-03 17:31:20 +08:00
    狗头,之前写过一种,能用,不确定是不是正确实践

    const getModule = () => new Promise(resolve => {
    setModule(oldState => {
    resolve(oldState);
    return oldState;
    });
    })

    用的时候

    setModule('2');
    await console.log(getModule()); // get 2
    Puteulanus
        18
    Puteulanus  
       2021-09-03 17:33:28 +08:00
    console.log(await getModule()) ,手滑
    huangyu2021
        19
    huangyu2021  
       2021-09-03 18:10:16 +08:00
    原理就是产生了闭包 一直是原来的值
    解决方法很多
    shengyueming
        20
    shengyueming  
       2021-09-03 20:27:41 +08:00
    1.setstate 的 callback
    2.componentdidupdate
    3.useeffect
    4 redux-thunk
    coolcoffee
        21
    coolcoffee  
       2021-09-03 23:17:17 +08:00
    @flybluewolf useReducer 操作异步方便吗?
    guoliim
        22
    guoliim  
       2021-09-04 18:18:44 +08:00
    setState 是 批处理
    还是 要再看一下 官方文档吧
    dengshen
        23
    dengshen  
       2021-09-05 00:53:58 +08:00 via iPhone
    嗯!千人千面。我用 vue/doge
    DOLLOR
        24
    DOLLOR  
       2021-09-05 22:18:40 +08:00
    把 getTableData 拎到组件外面,以参数形式把 module 传给 getTableData,并以返回值把请求的数据传回组件。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3036 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 12:49 · PVG 20:49 · LAX 05:49 · JFK 08:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.