Приложение React - загрузка выбранного массива в таблице пользовательского интерфейса материала без проверки чеков - PullRequest
0 голосов
/ 23 июня 2018

Так что я много работал много дней и искал, как это сделать. В моем приложении React есть таблица UI материалов. Я хочу загрузить таблицу, в которой, если у моего пользователя есть записи в выбранном массиве, он будет предварительно проверять проверки в DOM. Выбранный массив заполнен записями, которые я хочу, но моей таблице, которая использует onClick, я думаю, нужно событие, чтобы вызвать DOM для рендеринга чека. Это важная часть моего стола.

<TableBody>
                            {this.props.competitorData.map(competitor => {
                                const isSelected = this.props.isSelected(competitor.key);
                                return (
                                    <TableRow
                                        hover
                                        onClick={() => this.props.handleClick(competitor)}
                                        role="checkbox"
                                        aria-checked={isSelected}
                                        tabIndex={-1}
                                        key={competitor.key}
                                        selected={isSelected}
                                    >
                                        <TableCell padding="checkbox">
                                            <Checkbox checked={isSelected} />
                                        </TableCell>

У меня есть переключатель, который загружает мой стол. Он заполняет выбранный массив подмножеством данных, которые я хочу вызвать в componentWillMount. (это 2 таблицы, уровень 1 и уровень 2).

    componentWillMount() {
    this.renderChecks(this.props.team)
}

renderChecks(team) {
    const { selected1 } = this.state;
    const { selected2 } = this.state;
    let newSelected1 = [];
    let newSelected2 = [];

    team.map(teammate => {  
        if (teammate.tier === "1") {
            newSelected1 = newSelected1.concat(selected1, teammate.key)
        } else if (teammate.tier === "2") {
            newSelected2 = newSelected2.concat(selected2, teammate.key)
        }

        this.setState({ selected1: newSelected1 });
        this.setState({ selected2: newSelected2 });

    })      

}

По сути, мне нужен способ визуализации isSelected на основе другого списка, который является меньшим списком (команда представляет собой подмножество CompetitorData), который имеет те же ключи. Я перепробовал так много вещей, что многим перечислить здесь. Я ищу помощь в том, что нужно сделать, чтобы сделать эту работу, потому что ничего не сработало, и я не уверен, в каком направлении мне следует двигаться в данный момент. Я пробовал много вещей, которые, кажется, вызывают нестабильность в рендере. По сути, я пытался сделать isSelected более основанным на состоянии, но устанавливая и сбрасывая это состояние с помощью встроенных функций, таких как

 {() => this.myFunctionThatUpdatesIsSelectedState(Key)}

Они взрываются при рендере. Иногда вызывают безобразный бесконечный цикл.

Обновление

На основании поста @ Eld0w, приведенного ниже, это делает мой набор проверок.

     checkKeys(val) {
        return this.props.team.some(teammate => {
            return val.key === teammate.competitorKey;
        });
}

getCompetitors = () => {
    const { competitorData, team } = this.props;
    return competitorData.map(
        value => ({
            value,
            isSelected: this.checkKeys(value)
        })
    )
}

Таблицы теперь выглядят так.

                            <TableBody>
                            {this.getCompetitors().map(competitor => {
                                console.log('MYCOMPETITOR2::', competitor);
                                return (
                                    <TableRow
                                        hover
                                        onClick={event => this.props.handleClick(event, competitor.value)}
                                        role="checkbox"
                                        aria-checked={competitor.isSelected}
                                        tabIndex={-1}
                                        key={competitor.value.key}
                                        selected={competitor.isSelected}
                                    >
                                        <TableCell padding="checkbox">
                                            <Checkbox checked={competitor.isSelected} />
                                        </TableCell>

Есть небольшие проблемы, которых я не ожидал. Теперь моя таблица отображает только предварительно выбранные проверки, так как я не использовал мою предыдущую функцию isSelected, которая была:

 isSelected1 = key => this.state.selected1.indexOf(key) !== -1;

В основном мне нужно визуализировать существующие проверки, но также поддерживать стандартную функцию isSelected где-то в процессе. Если я что-нибудь подумаю или напишу что-нибудь об этом, я тоже обновлю здесь. Дальнейшие комментарии приветствуются.

Я думаю, мне нужно загрузить мою команду в выбранный массив, а затем запустить стандартную функцию isSelected. Но здесь я, кажется, сталкиваюсь с проблемами, потому что это основано на состоянии. Рендер сходит с ума от меня.

Окончательное обновление

Так что было поздно прошлой ночью. Мне просто нужно было изменить критерий, чтобы все это работало. Я загружаю массив моей команды в локальное состояние выбранного массива. Затем выполняется проверка выбранного свойства моего конкурента. Теперь он загружает мои предварительно выбранные, и пользователь может редактировать выборки в таблице с этой точки.

Окончательное решение

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

    componentWillMount() {
    this.renderChecks(this.props.team);
}

У меня есть многоуровневые столы. Это просто бизнес-логика (здесь не важно). teammate.competitorKey - это ключ, который я храню и который является тем же ключом, что и таблица большего размера, которая является CompetitorData. Мне это нужно, чтобы сравнить с работой.

renderChecks(team) {
    const { selected } = this.state;
    let newSelected = [];
    team.map(teammate => {
        if (teammate.tier === '1') {
            newSelected = newSelected.concat(selected, teammate.competitorKey)
            this.setState({ selected: newSelected });
        }
    })
}

getCompetitor теперь может просто проверить, существует ли ключ значения в массиве, используя include

getCompetitors = () => {
    const { competitorData, team } = this.props;
    console.log('THISSTATESELECTED:::', this.state.selected)
    return competitorData.map(
        value => ({
            value,
            isSelected: this.state.selected.includes(value.key)
        })
    )
}

И финальный стол выглядит как

                            <TableBody>
                            {this.getCompetitors().map(competitor => {
                                return (
                                    <TableRow
                                        hover
                                        onClick={event => this.handleClick(event, competitor.value)}
                                        role="checkbox"
                                        aria-checked={competitor.isSelected}
                                        tabIndex={-1}
                                        key={competitor.value.key}
                                        selected={competitor.isSelected}
                                    >
                                        <TableCell padding="checkbox">
                                            <Checkbox checked={competitor.isSelected} />
                                        </TableCell>

Я знаю, что это много пишет, но потратил много времени, пытаясь заставить все это работать. Я надеюсь, что это помогает кому-то, желающему сделать. Я постараюсь сделать это более излишним и, возможно, пойти по пути повторного выбора для оптимизации, но сейчас я собираюсь насладиться рабочим столом в течение дня. Еще раз спасибо @ Eld0w !!

1 Ответ

0 голосов
/ 23 июня 2018

Таким образом, вы хотите добавить isSelected реквизит в ваш массив конкурентов в зависимости от значений другого массива.Избегайте использования состояния, это только вспомогательные комбинации.

Простое решение

Вместо непосредственного отображения массива вашего конкурента, сопоставьте функцию, возвращающую массив.

getCompetitors = () => {
  const { competitors, team } = this.props;
  return competitors.map(
    competitor => ({
      ...competitor,
      isSelected: // criterion
    })
  )
}

По сути, это то, что это делает, деструктурирует объект и добавляет новое свойство isSelected благодаря оператору распространения ... (ES6)

В вашем рендере, затем вызовите this.getCompetitors().map(competitor => ...) вместо this.props.competitors.

Оптимизировать это решение

Вы захотите использовать такой плагин, как reselect, чтобы избежать бесполезной операции рендеринга.

const competitorSelector = createSelector(
  props => props.competitors,
  props => props.team,
  (competitors, team) => competitors.map(
    competitor => ({
      ...competitor,
      isSelected: // criterion 
    })
  )
)

и затем используйте его в своем рендере следующим образом:

this.competitorSelector(this.props) 

Вам также нужно будет использовать competitor.isSelected вместо isSelected, так как свойство теперь является частью вашего конкурента.свойства.

...