Important Details to Note When Using Antd

· 4 min read

Table-rowKey

index.js:1 Warning: [antd: Table] Each record in dataSource of table should have a unique key prop, or set rowKey of Table to an unique primary key, see https://u.ant.design/table-row-key

When using the Table component, we often see this warning in the browser console, which occurs because the row key is missing.

If rowKey is not specified, it defaults to rowIndex. So if the records truly don’t have any unique fields, you can leave it unspecified.

 getRecordKey = (record: T, index: number) => {
    const { rowKey } = this.props;
    const recordKey =
      typeof rowKey === 'function' ? rowKey(record, index) : (record as any)[rowKey!];
    warning(
      recordKey !== undefined,
      'Table',
      'Each record in dataSource of table should have a unique `key` prop, ' +
        'or set `rowKey` of Table to an unique primary key, ' +
        'see https://u.ant.design/table-row-key',
    );
    return recordKey === undefined ? index : recordKey;
  };

Note that if you specified a rowKey but still get a warning about missing keys, it’s likely because the key doesn’t exist.

key in Table-column

Unique key of this column, you can ignore this prop if you’ve set a unique dataIndex

A missing key won't trigger warning errors.

If you’ve configured dataIndex, you can omit the key, because when the key is undefined, it will use the column index instead.

Here’s part of the antd source code:

columns = columns.map((column, i) => {
      const newColumn = { ...column };
      newColumn.key = this.getColumnKey(newColumn, i);
      return newColumn;
    });
 getColumnKey(column: ColumnProps<T>, index?: number) {
    return column.key || column.dataIndex || index;
  }

Three parameters in Table-column render

The official Antd documentation describes render like this:

Function(text, record, index) {}	

We’re accustomed to implementing it with these three parameters, but is this always necessary? Not really.

For example, if a column doesn’t have dataIndex configured, in the actual render, we can do:

 render: (record) => this.props.isHidden? record.a : record.b)

Antd UI components are all encapsulated RC component libraries, mostly just modifying the UI. The column rendering logic is primarily in the rc-table source code.

In the source code, when getting the first parameter value for the column cell render function, it will first try to use dataIndex. If dataIndex doesn’t exist and is not a number basic type, it will return the current row record.

The conclusion is that when dataIndex doesn't exist and is not a number type, when the cell render actually executes, the first parameter value will be the record. But index is always the third parameter.

src/Cell/index.tsx

  const value = getPathValue<object | React.ReactNode, RecordType>(record, dataIndex);

src/utils/valueUtil.tsx

export function getPathValue<ValueType, ObjectType extends object>(
  record: ObjectType,
  path: DataIndex,
): ValueType {
  // Skip if path is empty
  if (!path && typeof path !== 'number') {
    return (record as unknown) as ValueType;
  }

  const pathList = toArray(path);

  let current: ValueType | ObjectType = record;

  for (let i = 0; i < pathList.length; i += 1) {
    if (!current) {
      return null;
    }

    const prop = pathList[i];
    current = current[prop];
  }

  return current as ValueType;
}

Uniqueness of value in TreeSelect-TreeNode

When constructing TreeNode data, note that value must be unique. The direct problem with duplicate values is display errors, because different nodeTitles corresponding to the same value will cause the component to display the latter one.

If your actual data indeed has the same values, analyze the differences - for example, add fixed prefixes or suffixes to create distinctions between them.

When duplicate values occur, you’ll get a warning, so if you encounter this situation, you definitely need to address it.

validator in Form

In a validator, returning true or false indicates whether the validation passes, and error messages depend on callback(new Error()). However, note that if the validator execution throws an error, the exception information won't be caught by the program. What appears to happen is that form.validate blocks indefinitely, and the program doesn't continue. The console also won't show any error messages.

setFieldsValue in Form

setFieldsValue during componentWillReceiveProps

When actually controlling form values, setFieldsValue is frequently used. However, note that if the component itself is wrapped with Form.create, don’t use the setFieldsValue method in the componentWillReceiveProps lifecycle, otherwise you may enter an infinite loop and cause memory leaks.

The reason can be understood this way: Form’s higher-order function wraps our component and indirectly calls componentWillReceiveProps, so setFieldsValue <=> componentWillReceiveProps would create an infinite loop.

Why do I say “may”? If you strengthen the conditional checks, it might not necessarily create an infinite loop. For example:

For details, click here

Of course, if the form component and the operation executing setFieldsValue are not in the same component, there’s generally no problem.

Authors
Developer, digital product enthusiast, tinkerer, sharer, open source lover