Зеркальное отображение положения при перемещении объектов из массива в массив в другой объект в React - PullRequest
2 голосов
/ 13 июня 2019

Когда я вызываю функцию createTodo, this.state.todos добавляется в новое задание. Объекты со свойством time хотят переместиться в массив times в объекте select, но times удваивается. Я думаю, что виноват метод .slice и копирование массива. Как обойти это?

Todo

class Todo extends Component {

  render() {
    return (
       <li>
        <div>
          {this.props.todo.description}
        </div>
      </li>
    )
  }
}

App

class App extends React.Component {
  constructor() {
    super();

    this.state = {

      todos: [
        {
          time: '00:00:10',
          description: 'Hello'
        },
        {
          time: '00:00:20',
          description: 'World'
        }
       ],
      todo: {
        'time': '00:00:30',
        'description': 'W'
      },
      select: {
        "times": [{ 'time': '00:00:40' }, { 'time': '00:00:50' }],
        "description": " ytytyty",
        "id": 3,
        "title": "gfgfgfgfgf"
      }
     };
  }



  addTodo = (todo) => {
    const news = this.state.todos.slice();
    news.push(this.state.todo);
    this.setState({ todos: news });
  };


  render() {

    this.state.todos.forEach(t => {
      if (t.time) this.state.select.times.push({
        time: t.time
      })
    });

    console.log(this.state.todos);
    console.log(this.state.select);

    return (
      <div>
        <ul>
          {
            this.state.todos
              .map((todo, index) =>
                <Todo
                  key={index}
                  index={index}
                  todo={todo}
                />
              )
          }
        </ul>
        <button onClick={this.createTodo}>button</button>
      </div>
    );
  }

console.log(this.state.select) -> return-->

times: [
 {time: "00:00:40"}
 {time: "00:00:50"}
 {time: "00:00:10"} //repeat
 {time: "00:00:20"} //repeat
 {time: "00:00:10"}
 {time: "00:00:20"}
 {time: "00:00:30"}
 title: "gfgfgfgfgf"
]

Ожидаемый эффект :

times: [
     {time: "00:00:40"}
     {time: "00:00:50"}
     {time: "00:00:10"}
     {time: "00:00:20"}
     {time: "00:00:30"}
     title: "gfgfgfgfgf"
    ]

DEMO https://stackblitz.com/edit/react-jfkwnu

Когда компонент загружен, он должен быть: selectTodo: {"times": [{'time': '00: 00: 40 '}, {' time ':' 00: 00: 50 '}], "description": "ytytyty", "id": 3, "title": "gfgfgfgfgf"}

Кнопка первого нажатия: -> selectTodo: {times: [{time: "00:00:40"} {time: "00:00:50"} {time: "00:00:10"} {time: " 00:00:20 "} {time:" 00:00:30 "} title:" gfgfgfgfgf "]," description ":" ytytyty "," id ": 3," title ":" gfgfgfgfgf "}

Изменение второго нажатия кнопки -> selectTodo: {times: [{time: "00:00:40"} {time: "00:00:50"} {time: "00:00:10"} {time: "00 : 00: 20 "} {'time': '00: 00: 30'}, {time:" 00:00:30 "} title:" gfgfgfgfgf "]" description ":" ytytyty "," id ": 3 , "title": "gfgfgfgfgf"}

1 Ответ

2 голосов
/ 13 июня 2019

Насколько я понял, вы хотите поддерживать оба значения todos и selectTodo независимо, но всегда все todos времена зеркально отражаются до selectTodo.times.

Подводя итог:

  1. состояние компонента устанавливается в конструкторе
  2. компонент крепления
  3. когда пользователь создает задачу
    1. если это первый раз, существующие todos отражаются в selectTodo.times
    2. подтолкнуть новый todo к todos и selectTodo.times.

Чтобы узнать, использовал ли пользователь уже метод createTodo, я просто добавил withInitialTodos в состояние. Он не совсем чистый, но он делает то, что вам нужно.

Обратите внимание, что, как сказал Берги в комментарии выше, вам следует избегать обновления состояния в методе render.

constructor() {
    super();

    this.state = {
        withInitialTodos: true,
        todos: [
            {
                time: '00:00:10',
                description: 'Hello'
            },
            {
                time: '00:00:20',
                description: 'World'
            }
        ],
        todo: {
            'time': '00:00:30',
            'description': 'W'
        },
        selectTodo: {
            "times": [{ 'time': '00:00:40' }, { 'time': '00:00:50' }],
            "description": " ytytyty",
            "id": 3,
            "title": "gfgfgfgfgf"
        }
    };
}

createTodo = (todo) => {
    this.setState({
        withInitialTodos: false,
        todos: [].concat(this.state.todos, this.state.todo),
        selectTodo: {
            ...this.state.selectTodo,
            times: [].concat(
                this.state.selectTodo.times,
                this.state.withInitialTodos ? this.state.todos.map(({ time }) => ({ time })): [],
                {
                  time: this.state.todo.time
                }
            )
        }
    });
}

render() {

    console.log(this.state.todos);
    console.log(this.state.selectTodo.times);

    return (
        <div>
            <ul>
                {this.state.todos.map((todo, index) => (
                    <Todo
                      key={index}
                      index={index}
                      todo={todo}
                    />
                )}
            </ul>
            <button onClick={this.createTodo}></button>
        </div>
    );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...