Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 当状态从挂钩更改时,不重新渲染_Reactjs - Fatal编程技术网

Reactjs 当状态从挂钩更改时,不重新渲染

Reactjs 当状态从挂钩更改时,不重新渲染,reactjs,Reactjs,编辑:谢谢大家的帮助。我需要更改数组的引用,并通过以下操作修复它: setData([...sorted]) 我目前正在呈现一个任务列表。这是功能组件中my return函数的一个片段: const [ data, setData ] = useState( mockData ) <tbody> { data.map(d => <TaskItem key={d.claimable} task={d}/>) } </tbody> 我认为问题位于d.

编辑:谢谢大家的帮助。我需要更改数组的引用,并通过以下操作修复它:

setData([...sorted])

我目前正在呈现一个任务列表。这是功能组件中my return函数的一个片段:

const [ data, setData ] = useState( mockData )

<tbody>
{ data.map(d => <TaskItem key={d.claimable} task={d}/>) }
</tbody>

我认为问题位于
d.claimable
下,我想它是
boolean
变量类型。您必须知道每个
道具都必须是唯一的。检查是否有例如
.id
属性,如果没有,请添加它

在对账过程中,关键道具的唯一性非常重要

带有一组子项的唯一标识符,以帮助确定哪些项已更改、已添加或已从列表中删除。它与这里描述的React的“列表和键”功能有关

和解很好

<tbody>
{ data.map(d => <TaskItem key={d.claimable} task={d}/>) }
</tbody>

{data.map(d=>)}

因为您使用的是相同的数组引用,所以需要使用

setData(old => "sorted data");
更改状态的引用并进行更新

function filterByContactAmount():void {
        let sorted = data.sort((a:any, b:any) => {
            let aTimesContacted:number = a.data.person.contact.list.reduce((acc:number, val:any):number => acc + val.history.length, 0)
            let bTimesContacted:number = b.data.person.contact.list.reduce((acc:number, val:any):number => acc + val.history.length, 0) 

            if ( aTimesContacted > bTimesContacted ) {
                return 1
            }

            if ( bTimesContacted > aTimesContacted ) {
                return -1
            }

            return 0;
        })

        console.log(sorted)
        setData(old => [...sorted]) // Sorted is the new state sorted
    }

您正在变异状态,另一个答案可能不是最好的,因为您仍在变异状态,然后使用已变异值的副本设置状态

还可以优化排序功能。或许可以尝试以下方法:

function filterByContactAmount() {
  let sorted = data
    .map(d => ({//map shallow copies the array
      ...d,//shallow copies the item
      sortedNum: d.data.person.contact.list.reduce(//do this once for every item, not for every time sort callback is called
        (acc, val) => acc + val.history.length,
        0
      ),
    }))
    .sort((a, b) => a.sortedNum - b.sortedNum);

  console.log(sorted);
  setData(sorted);
}

显示如何对数据进行排序data@BlackHole添加了排序印加你张贴链接到代码沙盒与您的代码?让我们调试一下。@loelsonk好的,给我一个sec@HMR用额外的评论来纠正你的评论是可以的,当你删除你的错误时,剩下的对话就会变得混乱claimable实际上是一个5位数的id。我试着在地图上添加一个索引,并将key设置为索引,但它没有与这个位混淆。Old指的是初始数组,“排序数据”指的是排序数组?因此:
setData(data=>sorted)
?@Syn我更新了代码,您需要对数据进行分解
setData(old=>…sorted)
您也可以执行
setData(sorted.slice())
Array.sort返回相同的数组引用,因此
let sorted=data.sort
行不会创建新引用
sorted===data
将是
true
仍在变异状态,排序和
setData(旧的=>[…排序])的效率非常低。
不需要,可以很好地使用
setData([…排序])
我同意,最好不要变异状态。@HMR我确实认为我的排序函数有点困难,但在尝试了你的方法之后,我在
reduce
@Syn上得到一个错误,声明
此表达式不可调用
。我在中复制了我的代码,没有编译错误。你能用你当前的代码更新你的问题吗?
function filterByContactAmount() {
  let sorted = data
    .map(d => ({//map shallow copies the array
      ...d,//shallow copies the item
      sortedNum: d.data.person.contact.list.reduce(//do this once for every item, not for every time sort callback is called
        (acc, val) => acc + val.history.length,
        0
      ),
    }))
    .sort((a, b) => a.sortedNum - b.sortedNum);

  console.log(sorted);
  setData(sorted);
}