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

Posted

技术标签:

【中文标题】React中将对象从数组移动到数组到另一个对象时的位置镜像【英文标题】:Mirroring the position when moving objects from the array to the array to another object in React 【发布时间】:2019-10-27 20:12:59 【问题描述】:

当我调用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 '], "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"

【问题讨论】:

你给出的预期效果例子是不是有错误? @dashdashzako。没有错误。我认为问题在于方法切片(复制新数组) @dashdashzako 你删除了你的答案吗? 是的,我想我错过了一些东西。如果您推送todos 而不清空它,它的值将始终推送到times,这是意料之中的。你能澄清一下 todos 是否应该持续存在,或者是否可以在每次addTodo 调用之间清空? @dashdashzako 你能举个例子吗?我想看看它是如何工作的 【参考方案1】:

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

总结一下:

    在构造函数中设置组件状态 组件安装 当用户创建待办事项时
      如果这是第一次,现有的todos 将被镜像到selectTodo.times 将新的待办事项推送至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>
    );

【讨论】:

组件加载时应该是: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" time: "00:00:20" time: "00:00:30" title: "gfgfgfgfgf" ], "description": "ytytyty", "id": 3, "title": “gfgfgfgfgf” 啊,所以你只想在按下按钮时添加todos。然后我会在状态中使用一种切换,我会更新答案。 是的。我单击另一个按钮更改-> selectTodo:次:[时间:“00:00:40”时间:“00:00:50”时间:“00:00:10”时间:“ 00:00:20" 'time': '00:00:30', time: "00:00:30" 标题:"gfgfgfgfgf" ] "description": "ytytyty", "id": 3、“标题”:“gfgfgfgfgf” 每次点击都会增加一个待办事项

以上是关于React中将对象从数组移动到数组到另一个对象时的位置镜像的主要内容,如果未能解决你的问题,请参考以下文章

关于ivx中将对象数组的某一列添加到另一对象数组中的经验总结

在javascript中将对象数组复制到另一个数组中(深度复制)

如何在 TypeScript Angular 2 中将 Json 对象数组映射到另一个普通 json 对象

如何在 C++ 中将字节数组发送到另一个进程

将Serializable数组从一个活动传递到另一个活动时的类Cast Exception

在Javascript / React中将对象转换为数组