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

时间:2019-11-21 20:17:13

标签: reactjs

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

setData([...sorted])

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

const [ data, setData ] = useState( mockData )

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

当我单击页面上的某个按钮时,数据集将被排序,然后我调用setData(sortedData)

由于某种原因,该表不会与已排序的数据一起重新呈现。我在这里做错了什么吗?

这是排序功能:

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(sorted)
    }

3 个答案:

答案 0 :(得分:1)

这是因为您使用的是数组的相同ref,所以您需要使用设置新数据

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
    }

答案 1 :(得分:1)

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

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

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);
}

答案 2 :(得分:0)

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

和解过程中关键道具的唯一性非常重要。

  

带有一组子代的唯一标识符,以帮助React找出哪些项已更改,已添加或已从列表中删除。它与此处所述的React的“列表和键”功能有关。

非常好article关于和解。

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