【问题标题】:Mirroring the position when moving objects from the array to the array to another object in ReactReact中将对象从数组移动到数组到另一个对象时的位置镜像
【发布时间】: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 你能举个例子吗?我想看看它是如何工作的

标签: javascript arrays reactjs ecmascript-6 javascript-objects


【解决方案1】:

据我了解,您希望独立维护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>
    );
}

【讨论】:

  • 组件加载时应该是: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”}
  • 每次点击都会增加一个待办事项
猜你喜欢
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
  • 2017-07-11
  • 2018-07-09
  • 1970-01-01
  • 2015-10-31
  • 2017-11-11
相关资源
最近更新 更多