记录在react函数组件传值(函数)导致的问题

464 阅读1分钟

上代码

// 父组件
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import Child from './Child'
import Fetch from 'common/fetch_v2';
import { stores } from '@/store'
export default () => {
  const [configTypeEnum, setconfigTypeEnum] = useState('')
  const { promissionStore = {} } = stores
  const { permission = [] } = promissionStore
  //根据权限初始化configTypeEnum
  useEffect(() => {
    if (permission.includes('permission_process_direct_enter_city_add')) {
      setconfigTypeEnum('DIRECT_ENTER_CITY')
      return
    }
    setconfigTypeEnum('IF_MEETING')
  }, [])
  const fetchData = (data) => {
    // 希望输出DIRECT_ENTER_CITY或者IF_MEETING,但是configTypeEnum输出了空
    console.log(configTypeEnum, 'configTypeEnum') 
    Fetch('/supervise/process/list', {
      method: 'post',
      param: {
        configTypeEnum,
      },
    })
  }, [])
  return (
  <SearchForm onSubmit={fetchData} />
  )
}
-----------------
子组件
import React, { useEffect } from 'react'
export default withRouter(
  ({ onSubmit }) => {
    const [form] = Form.useForm()

    useEffect(() => {
      handleSubmit()
    }, [])

    const handleSubmit = () => {
      form.validateFields().then(values => {
        onSubmit(values)
      })
    }

    return (
      <Form form={form}>
        <Button type="primary" onClick={handleSubmit}>搜索</Button>
      </Form>
    )
  },
)

分析产生问题的原因

函数组件

代码中fetchData输出的永远都是空字符串,这是因为函数组件在运行时都有独立的作用域,函数组件的变量是保存在运行时的作用域里面的,当我们有异步操作的时候,经常会碰到异步回调的变量引用是之前的,也就是旧的(这里也可以理解成闭包)。

class类组件

这个问题在class component不会出现,因为 class component 的属性和方法都存放在一个 instance 上,调用方式是: this.state.xxx 和 this.method 。因为每次都是从一个不变的 instance 上进行取值,所以不存在引用是旧的问题。

解决方法

用 useRef 返回的 immutable RefObject ( current 属性是可变的)来保存 state ,然后取值方式从 counter 变成了: counterRef.current 。

不知道还有没有更好、更优雅的解决方法,欢迎大佬们留言