Когда использовать React createFragment?

Я представляю ListView in React Native, которому удалось исправить это предупреждение React, но я не понимаю, как и почему он работает:

Warning: Any use of a keyed object should be wrapped in React.addons.createFragment(object) before being passed as a child.

// This array generates React Fragment warning.
var data1 = [{name: "bob"}, {name:"john"}]

// This array works, no warnings.
var data2 = [React.addons.createFragment({name: "bob"}),
             React.addons.createFragment({name: "john"})]

// This also works, no warnings.
var data3 = ["bob", "john"]

class Listings extends React.Component {
  constructor(props) {
    super(props)
    ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})

    this.state = {
      dataSource: ds.cloneWithRows(data),
    }
  }
  render() {
    return (
       <ListView
         dataSource={this.state.dataSource} 
         renderRow={(rowData) => <Text>{rowData}</Text>} />
    )
  }
}

Что такое фрагмент реакции? Когда это необходимо в реактиве? Почему вызываемый ключ вызывает это предупреждение?

Ответы

Ответ 1

Я разделяю свой ответ в двух разделах, чтобы охватить 2 основных момента, которые я вижу в вашем вопросе.

Раздел 1: Что такое фрагмент реакции?

Чтобы объяснить, что такое React Fragment, нам нужно сделать шаг назад и поговорить о React Keys.

Ключи help Реагировать, чтобы определить, какие элементы были изменены, добавлены или удалены. Они должны быть переданы элементам внутри массива, чтобы дать элементам устойчивое тождество (уникальность).

Лучший способ выбрать ключ - использовать строку, которая однозначно идентифицирует элемент списка среди своих братьев и сестер. Чаще всего вы будете использовать идентификаторы из ваших данных в качестве ключей. Вот практический пример:

render() {
    const todoItems = todos.map((todo) =>
      <li key={todo.id}>
        {todo.text}
      </li>
    );

    return todoItems;
}

Важно отметить, что todoItems на самом деле представляет собой массив элементов <li>.

Зная это, позвольте перейти к тому, почему вы получаете предупреждение в своем прецеденте.

В большинстве случаев вы можете использовать key prop, чтобы указать ключи на возвращаемых вами элементах рендеринга, как и в примере выше. Тем не менее, это ломается в одной ситуации: если у вас есть два набора детей, которые вам нужно переупорядочить, нет возможности поместить ключ в каждый набор без добавления элемента оболочки.

Вот классический пример из недавно обновленного документа React:

function Swapper(props) {
  let children;
  if (props.swapped) {
    children = [props.rightChildren, props.leftChildren];
  } else {
    children = [props.leftChildren, props.rightChildren];
  }
  return <div>{children}</div>;
}

Дети будут размонтироваться и монтироваться, когда вы изменяете опору swapped, потому что нет никаких ключей, помеченных на двух наборах детей.

Чтобы решить эту проблему, вы можете использовать надстройку createFragment, чтобы предоставить ключи для наборов дочерних элементов. Следуйте расширенному примеру, используя createFragment здесь.


Раздел 2: Но почему вы получаете это предупреждение?

В любом случае ошибка, с которой вы получаете ошибку, происходит просто потому, что вы пытаетесь интерполировать объект JavaScript (а не элемент JSX или строку) в некоторый JSX.

Хотя сообщение об ошибке предлагает использовать createFragment, чтобы исправить это, причина в том, что вы интерполируете переменную в некоторый JSX, который не является элементом строки или JSX, но на самом деле является каким-то другим видом объекта!

Такое вводящее в заблуждение предупреждение в вашем случае использования, не так ли?: -)