You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在表格中访问Formik Field组件当前值并按行区分

解决表格行内Formik Field值获取与区分问题

问题根源

你当前的写法存在两个核心问题:

  1. 每行单独创建一个Formik实例,按钮位于Formik组件外部,无法直接访问Formik内部的字段状态
  2. 所有Field的name都设为tokenAmount,没有区分不同行的输入,导致无法精准获取对应行的值

解决方案

将Formik实例提升到表格外层,统一管理所有行的输入状态,同时给每行的Field设置唯一的name标识:

1. 重构Formik结构与初始值

把Formik包裹在整个表格外面,初始化时根据token列表生成对应行的输入值:

<Formik
  initialValues={{
    // 用token的id作为key,初始化每行的tokenAmount为0
    tokenAmounts: tokens.reduce((acc, token) => {
      acc[token.id] = 0;
      return acc;
    }, {})
  }}
>
  {({ values }) => (
    <Form>
      <Table>
        {/* 表格表头... */}
        <TableBody>
          {tokens.map((token) => {
            const isItemSelected = // 你的选中逻辑
            const labelId = // 你的labelId逻辑
            return (
              <TableRow
                hover
                key={token.id}
                sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
                selected={isItemSelected}
                onClick={(event) => handleClick(event, token.address, 0, 0, "0")}
              >
                <TableCell padding="checkbox">
                  <Checkbox
                    color="primary"
                    checked={isItemSelected}
                    inputProps={{
                      'aria-labelledby': labelId,
                    }}
                  />
                </TableCell>
                <TableCell align="center">{token.name}</TableCell>
                <TableCell align="center">{token.symbol}</TableCell>
                <TableCell align="center">{token.address}</TableCell>
                <TableCell align="center">{token.maxAmount}</TableCell>
                <TableCell align="center">
                  {/* 用token.id作为name的唯一标识 */}
                  <Field
                    id={`tokenAmount-${token.id}`}
                    name={`tokenAmounts.${token.id}`}
                    type="number"
                    disabled={false}
                  />
                </TableCell>
                <TableCell align="center">
                  <Button
                    disabled={!isItemSelected}
                    onClick={() => {
                      // 从Formik的values中获取当前行对应的tokenAmount值
                      const amount = values.tokenAmounts[token.id];
                      approveERC20Token(token.address, props.smartVaultContract, amount);
                    }}
                    color="primary"
                    variant="contained"
                  >
                    Approve
                  </Button>
                </TableCell>
              </TableRow>
            );
          })}
        </TableBody>
      </Table>
    </Form>
  )}
</Formik>

2. 关键改动说明

  • 统一Formik实例:将Formik移到表格外层,所有行的输入都由同一个Formik管理,避免了实例隔离的问题
  • 唯一字段标识:每行Field的name设为tokenAmounts.${token.id},利用Formik的嵌套对象语法区分不同行的输入值
  • 直接从values取值:按钮点击时,通过Formik暴露的values对象,根据当前token的id精准获取对应行的输入值

备选方案:使用Formik Context(适合复杂组件结构)

如果你的表格行是独立组件,可以通过useFormikContext钩子在子组件中获取Formik的上下文:

// 表格行组件内部
import { useFormikContext } from 'formik';

const TokenTableRow = ({ token, isItemSelected, labelId, handleClick, approveERC20Token, smartVaultContract }) => {
  const { values } = useFormikContext();
  
  return (
    <TableRow
      // ...其他属性
    >
      {/* ...其他单元格 */}
      <TableCell align="center">
        <Field
          id={`tokenAmount-${token.id}`}
          name={`tokenAmounts.${token.id}`}
          type="number"
          disabled={false}
        />
      </TableCell>
      <TableCell align="center">
        <Button
          disabled={!isItemSelected}
          onClick={() => {
            const amount = values.tokenAmounts[token.id];
            approveERC20Token(token.address, smartVaultContract, amount);
          }}
          color="primary"
          variant="contained"
        >
          Approve
        </Button>
      </TableCell>
    </TableRow>
  );
};

内容的提问来源于stack exchange,提问作者Falcon Stakepool

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 15:45:43