当前位置: 首页 > 知识库问答 >
问题:

react.js - React 的 Hooks 为什么获取不到最新值?

李昊苍
2024-01-16

下面代码打印出来是空字符:这难道不是会更新的么:用的是蚂蚁的组件

import { Api_Module_Edit_Prepare, Api_Module_Edit_Save } from "../Request/Module"import { Input, Card, Form, Row, Col, Space, Collapse, Button, message } from 'antd';import { useNavigate, useParams } from "react-router-dom";import { useEffect, useState } from "react";import "../Css/Edit.sass"export function Component() {    const navigate = useNavigate();    const { module = "", id = 0 } = useParams();    const [primary] = Form.useForm();    const [messageApi, contextHolder] = message.useMessage();    const [tableActive, setTableActive] = useState<string>(``)    const [tableData, setTableData] = useState<Record<string, React.ReactNode>>({})    const [tabList, setTabList] = useState([]);    const onFinish = (data: any) => {        const params = { table: tableActive, data: data }        Api_Module_Edit_Save(module, [params]).then((res) => {            messageApi.success("保存成功")        })    }    // 渲染:表单【 主表 + 子表 】:Card    const formatTableData = (data: any) => data.reduce((loop: any, item: any, index: number) => ({        ...loop,        [item.table_name]: index === 0 ? renderFormItem(item) : renderTableItem(item)    }), {});    // 渲染:标签【 主表 + 子表 】    const formatTableTabs = (data: any) => data.map((item: any) => ({        key: item.table_name,        tab: item.display_name,    }))    // 渲染:主表表单    const renderFormItem = (table: any) => {        const renderFormItem = (columns: any) => columns.map((column: any) => (            <Col span={6} key={column.id}>                <Form.Item label={column.display_name} name={column.attr_name}>                    <Input maxLength={100} placeholder={`请输入`} disabled={column.build_in == 1} />                </Form.Item>            </Col>        ))        return (            <Form form={primary} name="project" onFinish={onFinish}>                {table.sections.map((section: any) => (                    <Collapse                        key={section.id}                        defaultActiveKey={['1']}                        items={[{                        key: section.id,                        label: section.display_name,                        children: <Row gutter={[16 ,16]} key={section.id}>{renderFormItem(section.columns)}</Row>                    }]} />                ))}            </Form>        )    }    // 渲染:子表数据    const renderTableItem = (data: any) => data.map((item: any) => ({    }))    // 渲染:公共操作    const renderPublicActions = [        <Space>            <Button type={`dashed`} onClick={() => navigate(-1)}>返回</Button>            <Button type={`primary`} onClick={() => primary.submit()}>保存</Button>        </Space>    ]    useEffect(() => {        Api_Module_Edit_Prepare(module).then((res) => {            setTableData(formatTableData(res.form))            setTabList(formatTableTabs(res.form))            setTableActive(res.form[0].table_name)        })    }, [module])    return (        <div className={`edit`}>            <Row gutter={[16, 16]}>                {contextHolder}                <Col span={24}>                    <Card                        actions={renderPublicActions}                        tabList={tabList}                        activeTabKey={tableActive}                        tabProps={{ size: 'middle' }}                        bodyStyle={{ padding: "15px"}}>                        {tableData[tableActive]}                    </Card>                </Col>            </Row>        </div>    )}Component.displayName = "Edit";}, [module])

共有1个答案

刘丰羽
2024-01-16

这里的设计存在一定的问题

  • onFinish 依赖了 tableActive
  • onFinish 又是在 setTableData(formatTableData(res.form)) 中被引用的
  • 首次进入这个 useEffect 的时候,tableActive 肯定是初始值,当请求完成更新 tableActive 后,并不会触发 setTableData(formatTableData(res.form)) 这条逻辑重新执行,所以导致产生了一个过期闭包,onFinish 始终引用的是初次的 tableActive
  • 因此这里 tableActive 其实也应该是这个 useEffect 的依赖项

但注意,加上之后,tableActive 变化,这个 useEffect 又会重新执行,会多请求一次,如果tableActive又存在变化的话会导致死循环,所以这块需要考虑下设计是否合理
image.png
image.png

 类似资料:
  • 本文向大家介绍React为什么要搞一个Hooks?相关面试题,主要包含被问及React为什么要搞一个Hooks?时的应答技巧和注意事项,需要的朋友参考一下 代码精简,一切都是fn 共享问题(组件,逻辑等) class原型指向问题混乱?https://overreacted.io/zh-hans/how-does-react-tell-a-class-from-a-function

  • 今天在工作中遇到一个react hooks问题,虽然解决了但是对于其中的原因不太理解,这里发出来和大家一起讨论一下。 具体代码如下,场景步骤如下: 点击一次,执行running后,isPolling设为true,并触发polling的useEffect 快速再点击一次,执行running,因为running前执行了cancle,所以这时候running内的isPolling应该是false,但实际

  • 求教useEffect这样监听对象的属性为什么不行呢?该怎么监听对象的属性呢?

  • RefHandle是子组件通过钩子useImperativeHandle中返回的对象类型声明,即抛给父组件中的ref上的属性的类型声明 为什么这个泛型是这样的, 这俩个泛型参数顺序不能更换, 我有点看不懂

  • 我有以下组件:- 我得到了错误:- 我怀疑它必须对多次调用setState的Submit按钮(onClick)做一些事情,但是我似乎无法解决问题。 因此,我有以下问题:- 如何修复点击()? 我想点击开始游戏按钮,然后触发 并 这样我就可以填满套牌,套牌1和套牌2。有没有办法做到这一点?目前,我已经创建了一个这取决于正在填充的甲板,这是用钩子做的正确方法吗? 谢谢你的帮助和时间!