最新消息:20210917 已从crifan.com换到crifan.org

【已解决】Reactjs中setState中移动列表元素的位置

JS crifan 709浏览 0评论
折腾一个Antd Pro的reactjs的前端项目:
现在需要去在拖动模式时调用的moveRows中,去setState更新列表的位置
且更新位置后,再去重新设置每个item中key的值(用最新的index+1)
之前的参考别人的代码是:
import update from 'immutability-helper'

  moveRow = (dragIndex, hoverIndex) => {
    console.log("moveRow: dragIndex=", dragIndex, ", hoverIndex=", hoverIndex)
    const { itemList } = this.state
    const dragRow = itemList[dragIndex]
    console.log("dragRow=", dragRow)

    let orderChangedItemList

    this.setState(
      update(this.state, {
        itemList: {
          $splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
        },
      }),
      // { itemList: orderChangedItemList}
      () => {
        console.log("moveRow: this.state.itemList=", this.state.itemList)
        this.props.onDragableListChange(this.state.itemList)
      }
    )
  }
但是其中的update的写法,不是很懂。
所以此处:
要么是彻底搞清楚update的写法,然后update后去调整kye值
要么是不用update,自己写js调整和移动列表元素的位置,期间很方便的可以调整key的值
js update splice
Updating an array element in javascript, splice push vs gets the value? – Stack Overflow
javascript – splice() not updating items order of array within knockout.js – Stack Overflow
javascript – Angular not updating dom after array splice – Stack Overflow
js immutability-helper update
Immutability Helpers – React
kolodny/immutability-helper: mutate a copy of data without changing the original source
// import update from 'react-addons-update';
import update from 'immutability-helper';

const state1 = ['x'];
const state2 = update(state1, {$push: ['y']}); // ['x', 'y']
有点看懂了,是update后,传递不同函数,再去操作
此处是update后,去splice
不可变数据的辅助工具(Immutability Helpers) – React 中文版 – 极客学院Wiki
所以此处就是去搞清楚:
js splice
JavaScript splice() 方法
“arrayObject.splice(index,howmany,item1,…..,itemX)
Array.prototype.splice() – JavaScript | MDN
“array.splice(start[, deleteCount[, item1[, item2[, …]]]])”
但是此处传入的是数组:
$splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
所以还是不懂。
然后看到了:
Immutability Helpers – React
* {$splice: array of arrays} for each item in arrays call splice() on the target with the parameters provided by the item.
才看懂:
此处是,传递了2个list:
  • [dragIndex, 1]
  • [hoverIndex, 0, dragRow]
然后分别调用splice
所以意思就是:
  • 从dragIndex开始,删除1个元素
  • 从hoverIndex,删除0个元素=不删除元素,新增一个元素dragRow
【总结】
最后去同时用update和自己写js更新key值:
import update from 'immutability-helper'


  moveRow = (dragIndex, hoverIndex) => {
    console.log("moveRow: dragIndex=", dragIndex, ", hoverIndex=", hoverIndex)
    const { itemList } = this.state
    const dragRow = itemList[dragIndex]
    console.log("dragRow=", dragRow)

    const oldItemList = this.state.itemList
    console.log("oldItemList=", JSON.stringify(oldItemList))
    const movedItemList = update(oldItemList, {
      $splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
    })
    console.log("movedItemList=", JSON.stringify(movedItemList))
    const updatedKeyItemList = []
    for(const keyValueList of movedItemList.entries()){
      const curIdx = keyValueList[0]
      const curNum = curIdx + 1
      const curItem = keyValueList[1]
      curItem.key = curNum
      updatedKeyItemList.push(curItem)
    }
    console.log("updatedKeyItemList=", JSON.stringify(updatedKeyItemList))

    this.setState(
      // update(this.state, {
      //   itemList: {
      //     $splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
      //   },
      // }),
      { itemList: updatedKeyItemList },
      () => {
        console.log("moveRow: this.state.itemList=", JSON.stringify(this.state.itemList))
        this.props.onDragableListChange(this.state.itemList)
      }
    )
  }
实现了列表重新排序。
输出:
moveRow: dragIndex= 3 , hoverIndex= 1
index.js:47 dragRow= {key: 4, speakerOrSong: "B", contentOrName: "4444", editable: true, isAudio: false}
index.js:50 oldItemList= [{"key":1,"speakerOrSong":"A","contentOrName":"1","editable":true,"isAudio":false},{"key":2,"speakerOrSong":"B","contentOrName":"22","editable":true,"isAudio":false},{"key":3,"speakerOrSong":"A","contentOrName":"333","editable":true,"isAudio":false},{"key":4,"speakerOrSong":"B","contentOrName":"4444","editable":true,"isAudio":false}]
index.js:54 movedItemList= [{"key":1,"speakerOrSong":"A","contentOrName":"1","editable":true,"isAudio":false},{"key":4,"speakerOrSong":"B","contentOrName":"4444","editable":true,"isAudio":false},{"key":2,"speakerOrSong":"B","contentOrName":"22","editable":true,"isAudio":false},{"key":3,"speakerOrSong":"A","contentOrName":"333","editable":true,"isAudio":false}]
index.js:63 updatedKeyItemList= [{"key":1,"speakerOrSong":"A","contentOrName":"1","editable":true,"isAudio":false},{"key":2,"speakerOrSong":"B","contentOrName":"4444","editable":true,"isAudio":false},{"key":3,"speakerOrSong":"B","contentOrName":"22","editable":true,"isAudio":false},{"key":4,"speakerOrSong":"A","contentOrName":"333","editable":true,"isAudio":false}]
index.js:80 DragableTable render: this.state.itemList= (4) [{…}, {…}, {…}, {…}]0: {key: 1, speakerOrSong: "A", contentOrName: "1", editable: true, isAudio: false}1: {key: 2, speakerOrSong: "B", contentOrName: "4444", editable: true, isAudio: false}2: {key: 3, speakerOrSong: "B", contentOrName: "22", editable: true, isAudio: false}3: {key: 4, speakerOrSong: "A", contentOrName: "333", editable: true, isAudio: false}length: 4__proto__: Array(0)
index.js:73 moveRow: this.state.itemList= [{"key":1,"speakerOrSong":"A","contentOrName":"1","editable":true,"isAudio":false},{"key":2,"speakerOrSong":"B","contentOrName":"4444","editable":true,"isAudio":false},{"key":3,"speakerOrSong":"B","contentOrName":"22","editable":true,"isAudio":false},{"key":4,"speakerOrSong":"A","contentOrName":"333","editable":true,"isAudio":false}]
其中最核心的是:
    const movedItemList = update(oldItemList, {
      $splice: [[dragIndex, 1], [hoverIndex, 0, dragRow]],
    })
可以把row,从dragIndex移动到hoverIndex
另外,对于splice的用途,这里:
JavaScript——slice和splice的区别 – 小 伍 – 博客园
的举例很清楚:
splice是JS中数组功能最强大的方法,它能够实现对数组元素的删除、插入、替换操作,返回值为被操作的值。
  • splice删除:  color.splice(1,2) (删除color中的1、2两项)
  • splice插入:  color.splice(1,0,’brown’,’pink’) (在color键值为1的元素前插入两个值)
  • splice替换:  color.splice(1,2,’brown’,’pink’)  (在color中替换1、2元素)
var color = new Array('red','blue','yellow','black');
var color2 = color.splice(2,3,'brown','pink');
alert(color);     //  red,blue,brown,pink
alert(color2);    //  yellow,black

转载请注明:在路上 » 【已解决】Reactjs中setState中移动列表元素的位置

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
92 queries in 0.202 seconds, using 23.40MB memory