上代码
// 父组件
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 。