Материал пользовательский интерфейс масштабировать, затем удалить - PullRequest
0 голосов
/ 06 ноября 2018

Я создаю динамический интерфейс, где пользователь может добавлять и удалять динамическое количество элементов. Есть кнопка добавления, и у каждого элемента есть кнопка удаления. У меня есть каждый элемент, содержащийся в Zoom, чтобы придать ему анимацию. При добавлении нового элемента это работает хорошо. Я сталкиваюсь с проблемой, когда удаляю элемент, так как он отменяет отображение элемента из DOM, и анимация теряется. Существует ли своего рода обратный вызов для переходов, который я мог бы использовать для обновления массива, содержащего элементы, после его анимации? Или, возможно, лучшее решение?

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

Код Песочница: https://codesandbox.io/s/l2lly078kq

import React from "react";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";
import Grid from "@material-ui/core/Grid";
import Paper from "@material-ui/core/Paper";
import Zoom from "@material-ui/core/Zoom/Zoom";

let itemCount = 0;

export default class extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      items: [],
      items2: [],
      hiddenItems: []
    };
  }

  handleAddItem = () => {
    let items = this.state.items;
    items.push(`Item ${itemCount++}`);
    this.setState({ items });
  };

  handleDeleteItem = index => {
    let items = this.state.items;
    items.splice(index, 1);
    this.setState({ items });
  };

  handleAddItem2 = () => {
    let items2 = this.state.items2;
    items2.push(`Item ${itemCount++}`);
    this.setState({ items2 });
  };

  handleDeleteItem2 = index => {
    let hiddenItems = this.state.hiddenItems;
    hiddenItems.push(index);
    this.setState({ hiddenItems });
  };

  render() {
    const { items, items2, hiddenItems } = this.state;

    return (
      <React.Fragment>
        <Typography>
          Items animate in, but instantly are removed instead of animating out
        </Typography>
        <Button onClick={this.handleAddItem}>Add</Button>
        <Grid container spacing={16}>
          {items.map((item, index) => (
            <Zoom in={true}>
              <Grid item xs={3}>
                <Paper>
                  <Button onClick={() => this.handleDeleteItem(index)}>
                    Delete
                  </Button>
                  {item}
                </Paper>
              </Grid>
            </Zoom>
          ))}
        </Grid>
        <br />
        <br />
        <Typography>
          Items animate in and out, but the grid does not collapse
        </Typography>
        <Button onClick={this.handleAddItem2}>Add</Button>
        <Grid container spacing={16}>
          {items2.map((item, index) => (
            <Zoom in={!hiddenItems.includes(index)}>
              <Grid item xs={3}>
                <Paper>
                  <Button onClick={() => this.handleDeleteItem2(index)}>
                    Delete
                  </Button>
                  {item}
                </Paper>
              </Grid>
            </Zoom>
          ))}
        </Grid>
      </React.Fragment>
    );
  }
}

enter image description here

Ответы [ 2 ]

0 голосов
/ 10 июня 2019

Вы можете использовать обратный вызов onExited (Переходы Material-UI построены на группе переходов реагирования. Переход - см. Здесь документы http://reactcommunity.org/react-transition-group/transition#Transition-prop-onExited) пропуска компонента Zoom, чтобы удалить элемент из массива элементов после завершения Zoom перехода, нажав кнопку, чтобы начать переход. Например:

<Zoom
    in={this.state.deletedItem !== item}
    onExited={() => this.handleDeleteItem(item)}
>

<Button onClick={() => this.handleRemoveItem(item)}>

Как видно из кода, я также:

  • Удалил массив hiddenItems и просто сохранил текущий удаляемый элемент - in={this.state.deletedItem !== item}.

Вы можете посмотреть мою версию здесь: https://codesandbox.io/s/heuristic-booth-fnwwk

Этот подход также позволяет отменить переход, если удаление не удалось (например, если вы вызываете API для удаления), поскольку события перехода и удаления разделены. См. Следующий код для примера https://codesandbox.io/s/flamboyant-babbage-y506f.

0 голосов
/ 07 ноября 2018

попробуйте перейти по ссылке

введите описание ссылки здесь

Я изменил ваш код следующим образом

import React from "react";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";
import Grid from "@material-ui/core/Grid";
import Paper from "@material-ui/core/Paper";
import Zoom from "@material-ui/core/Zoom/Zoom";

let itemCount = 0;

export default class extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      items: [],
      items2: [],
      hiddenItems: [],
      hiddenItems2: []
    };
  }

  handleAddItem = () => {
    let items = this.state.items;
    items.push(`Item ${itemCount++}`);
    this.setState({ items });
  };

  handleDeleteItem = index => {
    let hiddenItems = this.state.hiddenItems;
    hiddenItems.push(index);
    this.setState({ hiddenItems });

    // let items = this.state.items;
    // items.splice(index, 1);
    // this.setState({ items });
  };

  handleAddItem2 = () => {
    let items2 = this.state.items2;
    items2.push(`Item ${itemCount++}`);
    this.setState({ items2 });
  };

  handleDeleteItem2 = index => {
    let hiddenItems2 = this.state.hiddenItems2;
    hiddenItems2.push(index);
    this.setState({ hiddenItems2 });
  };

  render() {
    const { items, items2, hiddenItems, hiddenItems2 } = this.state;

    if (hiddenItems.length > 0) {
      console.log(hiddenItems);

      setTimeout(() => {
        let items = this.state.items;
        for (var item of hiddenItems) {
          items.splice(item, 1);
        }

        this.setState({ hiddenItems: [], items });
      }, 250);
    }

    return (
      <React.Fragment>
        <Typography>
          Items animate in, but instantly are removed instead of animating out
        </Typography>
        <Button onClick={this.handleAddItem}>Add</Button>
        <Grid container spacing={16}>
          {items.map((item, index) => (
            <Zoom in={!hiddenItems.includes(index)}>
              <Grid item xs={3}>
                <Paper>
                  <Button onClick={() => this.handleDeleteItem(index)}>
                    Delete
                  </Button>
                  {item}
                </Paper>
              </Grid>
            </Zoom>
          ))}
        </Grid>
        <br />
        <br />
        <Typography>
          Items animate in and out, but the grid does not collapse
        </Typography>
        <Button onClick={this.handleAddItem2}>Add</Button>
        <Grid container spacing={16}>
          {items2.map((item, index) => (
            <Zoom in={!hiddenItems2.includes(index)}>
              <Grid item xs={3}>
                <Paper>
                  <Button onClick={() => this.handleDeleteItem2(index)}>
                    Delete
                  </Button>
                  {item}
                </Paper>
              </Grid>
            </Zoom>
          ))}
        </Grid>
      </React.Fragment>
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...