Javascript React Hooks:组件在状态更新时重新渲染一步

Javascript React Hooks:组件在状态更新时重新渲染一步,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有一个对象数组,它应该按照用户定义的属性(在下拉列表中)进行排序。代码如下: import React, {useState, useEffect} from 'react'; const repos = [ { name: 'repo1', forks_count: 5, stargazers_count: 3, updated_at: 12 }, { name: 'repo2', forks_count: 7, star

我有一个对象数组,它应该按照用户定义的属性(在下拉列表中)进行排序。代码如下:

import React, {useState, useEffect} from 'react';

const repos = [
  {
    name: 'repo1',
    forks_count: 5,
    stargazers_count: 3,
    updated_at: 12
  },
  {
    name: 'repo2',
    forks_count: 7,
    stargazers_count: 2,
    updated_at: 17
  },
  {
    name: 'repo3',
    forks_count: 8,
    stargazers_count: 11,
    updated_at: 5
  }
];

function App() {
  const[data, setData] = useState([]);
  const[sortType, setSortType] = useState('stars');

  useEffect(() => {
    const sortRepos = (type) => {
      const types = {
          stars: 'stargazers_count',
          forks: 'forks_count',
          upd: 'updated_at'
      };
      const sortProperty = types[type]; 
      const sorted = repos.sort((a,b) => b[sortProperty] - a[sortProperty]);         
      setData(sorted);
    }; 

    sortRepos(sortType);
    }, [sortType]);


  return (
    <div className="App">
      <select onChange={(e) => setSortType(e.target.value)}>
        <option value='stars'>Stars</option>
        <option value='forks'>Forks</option>
        <option value='upd'>Updated</option>
      </select>

      <div >
      {data.map(repo => (
            <div key={repo.name}>
              <div>Name {repo.name}</div>
              <div>Forks {repo.forks_count}</div>
              <div>Stars {repo.stargazers_count}</div>
              <div>Update {repo.updated_at}</div>
            </div>
        ))} 
      </div>
    </div>
  );
}
import React,{useState,useffect}来自“React”;
常数回购=[
{
名称:'repo1',
叉子数:5,
观星者人数:3,
更新时间:12
},
{
名称:'repo2',
叉子数:7,
观星者人数:2,
更新时间:17
},
{
名称:'repo3',
叉子数:8,
观星者人数:11,
更新时间:5
}
];
函数App(){
const[data,setData]=useState([]);
const[sortType,setSortType]=useState('stars');
useffect(()=>{
const sortRepos=(类型)=>{
常量类型={
星星:“看星星的人”,
叉子:“叉子数”,
upd:“更新时间”
};
const sortProperty=types[type];
const sorted=repos.sort((a,b)=>b[sortProperty]-a[sortProperty]);
设置数据(已排序);
}; 
sortRepos(sortType);
},[sortType]);
返回(
setSortType(e.target.value)}>
星星
叉子
更新
{data.map(repo=>(
名称{repo.Name}
Forks{repo.Forks\u count}
星星{repo.stargazers_count}
更新{repo.updated_at}
))} 
);
}
但问题是,更改下拉列表中的值后,排序后的数据会重新渲染一步

我做错了什么?我的猜测是,问题在于比较对象,因为我已经测试过在数据变量中设置原语值,并且一切正常。但不是用物体

问题在于(某种程度上是间接的)您正在直接修改状态数据,这是错误的。您正在对处于状态的数组调用
sort
,该数组将对其进行适当排序。您需要复制它并对副本进行排序。您没有及时看到更新,因为您正在使用它已经拥有的相同数组调用
setData
,因此它忽略了调用

const sorted = [...repos].sort((a,b) => b[sortProperty] - a[sortProperty]);         
// −−−−−−−−−−−−^^^^^^^^^^
实例:

const{useState,useffect}=React;
常数回购=[
{
名称:'repo1',
叉子数:5,
观星者人数:3,
更新时间:12
},
{
名称:'repo2',
叉子数:7,
观星者人数:2,
更新时间:17
},
{
名称:'repo3',
叉子数:8,
观星者人数:11,
更新时间:5
}
];
函数App(){
const[data,setData]=useState([]);
const[sortType,setSortType]=useState('stars');
useffect(()=>{
const sortRepos=(类型)=>{
常量类型={
星星:“看星星的人”,
叉子:“叉子数”,
upd:“更新时间”
};
const sortProperty=types[type];
const sorted=[…repos].sort((a,b)=>b[sortProperty]-a[sortProperty]);
设置数据(已排序);
}; 
sortRepos(sortType);
},[sortType]);
返回(
setSortType(e.target.value)}>
星星
叉子
更新
{data.map(repo=>(
名称{repo.Name}
Forks{repo.Forks\u count}
星星{repo.stargazers_count}
更新{repo.updated_at}
))} 
);
}
render(,document.getElementById(“根”))