Анимировать список div в React - PullRequest
       0

Анимировать список div в React

0 голосов
/ 05 декабря 2018

Я экспериментирую с простой анимацией в React, пытаясь переместить все синие div в соответствии с setInterval и функцией 'move'.Div создаются, когда один щелчок где-то на фоне.Я нашел решение для анимации всех div, добавив this.addDiv(event) к componentDidMount, но в консоли покажу мне непредсказуемый результат.Состояние для this.state.position показывает мне NaN.Другая проблема заключается в том, что первый созданный div не перемещается немедленно (обновляется до следующего клика).Кроме того, я боюсь, что код выглядит ужасно и не поддерживает логику React.

Есть идеи, как улучшить эту анимацию?

Код готов к редактированию (необходимо раскомментировать this.addDiv(event) в componentDidMount) -> https://codesandbox.io/s/73x3ljq6z0

import React from "react";
import ReactDOM from "react-dom";

const styleApp = {
  textAlign: 'center',
  width: '100vw',
  height: '100vh'
}


class App extends React.Component {
  constructor() {
    super();
    this.state = {
      position: [],
      intervalId: null
    };
  }

  componentDidMount() {
    const intervalId = setInterval(() => {
      this.move()
      this.renderList()
      //this.addDiv(event)  //start moving almoust all div's, without first one. In the console this.state.position show: NaN
      }, 1000);
    this.setState({ intervalId });
  }

  componentWillUnmount() {
    clearInterval(this.state.intervalId);
  }

  addDiv = event => {
    const newStateArray = [...this.state.position];
    newStateArray.push([event.pageX, event.pageY]);
    this.setState({
      x: event.pageX,
      y: event.pageY,
      position: newStateArray
    });
    this.setState((state) => {
      console.log(`positions for all clicks: ${state.position}`);
    });
  };
  move = () => {
    this.setState((state, props) => {
        state.position.forEach((item, index) => {
          let i = item;
          i[0] += 20;
          i[1] += 1;
          console.log(i);
        })
    });
  };

  renderList = () => {
    return ( <div> 
      {this.state.position.map((item, index) => (
        <div
          key={index}
          style={{
            position: "absolute",
            width: "30px",
            height: "30px",
            background: "blue",
            top: this.state.position[index][1],
            left: this.state.position[index][0]
          }}
        />
      ))}
      </div> )
  }

  render() {
    return (
      <div onClick={this.addDiv} className="App" style={styleApp}>
        <p>This is x: {this.state.x}</p>
        <p>This is y: {this.state.y}</p>
        <div>
          { this.renderList() }
        </div>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

1 Ответ

0 голосов
/ 06 декабря 2018

Основная проблема для вещей, которые не обновляются, заключается в том, что вы изменяете состояние.

React не будет обновлять состояние, пока не обнаружит разницу, и он использует строгие проверки на равенство для быстрой проверки.Итак, вам нужно убедиться, что вы возвращаете новый объект, и вам нужно убедиться, что вы что-то возвращаете, когда выполняете вызов функции для setState.Вот ваш move метод с несколькими встроенными комментариями

move = () => {
  this.setState((state, props) => {
    // foreach does not return anything
    state.position.forEach((item, index) => {
      let i = item;
      // these next two lines mutate the array in place
      i[0] += 20;
      i[1] += 1;
      console.log(i);
    })
  });
};

Как правило, когда вы вызываете setState, вы действительно хотите установить состояние, так что сделайте это здесь с map вместоforEach и вернуть новые массивы.

move = () => {
  // setState expects a new object for a state, below the `prev => ({})` syntax
  // implicitly returns a new object
  this.setState(prev => ({
    // spread the previous state
    ...prev,
    // map returns a new array, and our implementation, here, returns new sub-arrays and uses some destructuring to make the code easier to read.
    position: prev.position.map(([x, y], index) => [x + 20, y + 1]),
  }));
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...