我已经设置了一个MUI表,它的最后一行包含几个TextField(为了可读性,go 掉了内容):

[Generated rows...]
<TableRow>
  <TableCell component="th" scope="row">
    <TextField/>
  </TableCell> ...

  <TableCell>
    <Button variant="outlined" onClick={() => addFond()}>
        <Add />
    </Button>
  </TableCell>
</TableRow>

以上行将从来自永久存储状态的数组中生成. 使用addFond()按钮和功能添加一行:

const addFond = () => {
  userDefaults.assuranceVie ??= {}
  userDefaults.assuranceVie.tableFondsVI ??= []
  userDefaults.assuranceVie.tableFondsVI.push({ ...formik.values, id: uuidv4() })
  setDefaults(userDefaults)
}

我为新行使用了Formik表单,并希望为最后一行之上的所有迭代行创建一个新的Formik行.

当单击addFond()按钮时,我预计状态会更改并重新呈现整个组件. 我让console.log在组件的顶层打印状态,但在单击时不打印任何内容.

请注意,该表组件被嵌入到更高阶的标记中.

After resolution edit :

在使用setter之后,我无法修改状态对象并期望更改检测工作,因为状态实际上并没有更改.

推荐答案

状态更改不会触发重现

事实上,没有任何州的变化.重新渲染不会被触发,因为之前的状态值与新值完全相同,因为您正在改变它.

userDefaults.assuranceVie ??= {}-状态Mutations .

您应该基于setState的回调函数,以确保引用当前状态,并且应该返回一个新对象以避免Mutations .

const addFond = () => {
  setDefaults((prev) => ({
     ...prev,
     assuranceVie: {
        ...(prev.assuranceVie || {}), // in case if not exists
        tableFondsVI: [
           ...(prev.assuranceVie?.tableFondsVI || []), 
           { ...formikValues, id: uuidv4() }
        ],
     }
  });
}

Reactjs相关问答推荐

使用setInterval判断数据的时间,然后在过期后从对象中删除;遇到性能问题

Reaction路由的问题-在Effect使用API调用响应设置状态之前呈现页面

使用Reaction-Hook-Form时未激发React.js onBlur事件

为多租户SSO登录配置Azure AD应用程序

如何使用TouchStart/TouchEnd在Table ReactJS中交换位置?

滚动视图样式高度没有任何区别

如何在一个 Next.js 项目中使用两种布局?

Redux 工具包不更新状态

显示我是否加入聊天应用程序时出现问题

无法通过react 路由中的链接传递信息

useEffect内部的RETURN语句在首次按钮点击事件中似乎无效的原因是什么?

Firebase查询返回随机用户数据,而不是过滤后的用户数据

@react-three/postprocessing 没有匹配的从 three.module.js 导出以导入WebGLMultisampleRenderTarget

有没有办法根据 Rechart 中的 activeDot 更改值?

React Native map 中的初始zoom 级别

如何制作基于对象 struct 呈现数据的可重用组件?

react 路由dom没有路由匹配位置错误/在路由中制作组件

设置 Material UI 表格默认排序

如何在 Reactjs 中判断受保护路由上的用户角色?

警告:您在没有 `onChange` 处理程序的情况下为表单字段提供了 `value` 属性