javascript - 在 React 中将对象从数组移动到数组到另一个对象时镜像位置

标签 javascript arrays reactjs ecmascript-6 javascript-objects

当我调用createTodo函数时,this.state.todos被添加到新的待办事项中。具有 time 属性的对象想要移动到对象 select 中的 times 数组,但是 times 被加倍。 我认为问题在于 .slice 方法和复制数组。如何解决这个问题?

待办事项

class Todo extends Component {

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

应用程序

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"
    ]

演示 https://stackblitz.com/edit/react-jfkwnu

当组件加载时,它应该是: selectTodo: {"times": [{'time': '00: 00: 40 '}, {' time ':' 00: 00: 50 '} ]、“描述”:“ytytyty”、“id”:3、“标题”:“gfgfgfgfgf”}

首次点击按钮:-> selectTodo: {times: [{time: "00:00:40"} {time: "00:00:50"} {time: "00:00:10"} {时间:"00:00:20"} {时间:"00:00:30"} 标题:"gfgfgfgfgf"],"描述":"ytytyty","id":3,"标题":"gfgfgfgfgf “}

第二次单击按钮更改 -> selectTodo: {times: [{time: "00:00:40"} {time: "00:00:50"} {time: "00:00:10"} {时间:"00:00:20"} {'时间':'00:00:30'}, {时间:"00:00:30"}标题:"gfgfgfgfgf"]"描述":"ytytyty",“id”:3,“标题”:“gfgfgfgfgf”}

最佳答案

据我了解,您希望独立维护 todosselectTodo,但始终将所有 todos 时间镜像到 selectTodo.times.

总结一下:

  1. 组件状态在构造函数中设置
  2. 组件安装
  3. 当用户创建待办事项时
    1. 如果这是第一次,现有的 todos 将镜像到 selectTodo.times
    2. 将新待办事项推送到 todosselectTodo.times

为了了解用户是否已经使用了 createTodo 方法,我刚刚将 withInitialTodos 添加到状态中。它并不是很干净,但它可以满足您的需要。

请注意,正如 Bergi 在上面的评论中所说,您应该避免在 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>
    );
}

关于javascript - 在 React 中将对象从数组移动到数组到另一个对象时镜像位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56577014/

相关文章:

javascript - 抢占式getBBox计算

javascript - 如何使用rest api中的antd table组件渲染datagrid

javascript - react : problems with . ..传播

JavaScript:调用外部函数时调用 Array.reduce,并且外部函数有参数

javascript - 发出警报时,Sweet alert 2 未显示为模态

javascript - zepto 动画 id 的问题

javascript - Select - Angular 2 的设定值

javascript - Knockout Kendo Grid 数据绑定(bind)事件

c - C 路口面积

arrays - Array.Sort(array, Comparison<t>) 如何执行?