React不断重新渲染我通过映射对象条目(useState变量)创建的组件。

huangapple go评论74阅读模式
英文:

React keeps re-rendering my components that i made by mapping over an object.entries(useState variable)

问题

我已经翻译好了您提供的内容:

我已经在React.js中编写了代码它可以正常工作渲染了一个简单的表格),但是表格元素每秒都在重新渲染当我尝试突出显示某些内容时它立即取消突出显示

这是一个从Lichess API获取数据的React表格
它可以渲染一个表格但是td和tr元素不停地刷新

我尝试了以下代码

import './Recent.css';
import { React, useState, useEffect, useMemo } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSort, faSortUp, faSortDown } from '@fortawesome/free-solid-svg-icons';

import * as fetch from 'node-fetch';

function Recent() {
const [ratings, setRatings] = useState({});
const [headers, setHeaders] = useState([""]);
const [loaded, setLoaded] = useState(false);
const [vState, setVState] = useState('default');
const [dState, setDState] = useState('default');
const [rState, setRState] = useState('default');

const fetchRatings = () => {
fetch('lichesslinkthatyoudontgettosee')
.then(response => {
return response.json()
})
.then(data => {
setRatings(data);
setHeaders(["Variant", "Date", "Rating"]);
setLoaded(true);
});
}

useEffect(() => {
fetchRatings()
}, []);

function vCycle(vState) {
if (vState === 'default') {
setVState('dsc');
setDState('default');
setRState('default');
} else if (vState === 'dsc') {
setVState('asc');
} else {
setVState('default');
}
}

function dCycle(dState) {
if (dState === 'default') {
setDState('dsc');
setVState('default');
setRState('default');
} else if (dState === 'dsc') {
setDState('asc');
} else {
setDState('default');
}
}

function rCycle(rState) {
if (rState === 'default') {
setRState('dsc');
setVState('default');
setDState('default');
} else if (rState === 'dsc') {
setRState('asc');
} else {
setRState('default');
}
}
return (
<div className="container" style={{display: loaded ? 'flex' : 'none'}}>

Most Recent

<th onClick={() => vCycle(vState)}>{headers[0]} <FontAwesomeIcon fixedWidth transform="shrink-3" icon={vState === 'default' ? faSort : vState === 'asc' ? faSortUp : faSortDown} />

<th onClick={() => dCycle(dState)}>{headers[1]} <FontAwesomeIcon fixedWidth transform="shrink-3" icon={dState === 'default' ? faSort : dState === 'asc' ? faSortUp : faSortDown} />

<th onClick={() => rCycle(rState)}>{headers[2]} <FontAwesomeIcon fixedWidth transform="shrink-3" icon={rState === 'default' ? faSort : rState === 'asc' ? faSortUp : faSortDown} />

{Object.values(ratings).filter(o => o.points.length).map((item) => {
return (

)
}) ?? null}

{item.name} {item.points.at(-1)[1] + 1 + "/" + item.points.at(-1)[2] + "/" + item.points.at(-1)[0].toString().slice(2, 4) } {item.points.at(-1)[3]}

);
}

// const displayInfo = () => (

// )

export default Recent;


表格不断地重新渲染,您该如何修复这个问题:

```javascript
import './App.css';
import Recent from './components/Recent';

function App() {
  return (
    <Recent />
  )
}

export default App;
英文:

i have written code in react js and it works (it renders a simple table) but the table elments keep rerendering every second and when i try to highlight something it unhighlights immediately

this is a react table that basically pulls from lichess api
it renders a table but the the td and trs keep refreshing constantly

i tried this

import &#39;./Recent.css&#39;;
import { React, useState, useEffect, useMemo } from &#39;react&#39;;
import { v4 as uuidv4 } from &#39;uuid&#39;;
import { FontAwesomeIcon } from &#39;@fortawesome/react-fontawesome&#39;
import { faSort, faSortUp, faSortDown } from &#39;@fortawesome/free-solid-svg-icons&#39;

import * as fetch from &#39;node-fetch&#39;;

function Recent() {
  const [ratings, setRatings] = useState({});
  const [headers, setHeaders] = useState([&quot;&quot;]);
  const [loaded, setLoaded] = useState(false);
  const [vState, setVState] = useState(&#39;default&#39;);
  const [dState, setDState] = useState(&#39;default&#39;);
  const [rState, setRState] = useState(&#39;default&#39;);

  const fetchRatings = () =&gt; {
    fetch(&#39;lichesslinkthatyoudontgettosee&#39;)
      .then (response =&gt; {
        return response.json()
      })
      .then (data =&gt; {
        setRatings(data);
        setHeaders([&quot;Variant&quot;, &quot;Date&quot;, &quot;Rating&quot;]);
        setLoaded(true);
      });
  }

  useEffect(() =&gt; {
    fetchRatings()
  }, []);

  function vCycle(vState) {
    if (vState === &#39;default&#39;) {
        setVState(&#39;dsc&#39;);
        setDState(&#39;default&#39;);
        setRState(&#39;default&#39;);
    } else if (vState === &#39;dsc&#39;) {
        setVState(&#39;asc&#39;);
    } else {
        setVState(&#39;default&#39;);
    }
  }

  function dCycle(dState) {
    if (dState === &#39;default&#39;) {
        setDState(&#39;dsc&#39;);
        setVState(&#39;default&#39;);
        setRState(&#39;default&#39;);
    } else if (dState === &#39;dsc&#39;) {
        setDState(&#39;asc&#39;);
    } else {
        setDState(&#39;default&#39;);
    }
  }

  function rCycle(rState) {
    if (rState === &#39;default&#39;) {
        setRState(&#39;dsc&#39;);
        setVState(&#39;default&#39;);
        setDState(&#39;default&#39;);
    } else if (rState === &#39;dsc&#39;) {
        setRState(&#39;asc&#39;);
    } else {
        setRState(&#39;default&#39;);
    }
  }
  return (
    &lt;div className=&quot;container&quot; style={{display: loaded ? &#39;flex&#39; : &#39;none&#39;}}&gt;
      &lt;h2&gt;Most Recent&lt;/h2&gt;
      &lt;table&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;th onClick={() =&gt; vCycle(vState)}&gt;{headers[0]} &lt;span&gt;&lt;FontAwesomeIcon fixedWidth transform=&quot;shrink-3&quot; icon={vState === &#39;default&#39; ? faSort : vState === &#39;asc&#39; ? faSortUp : faSortDown} /&gt;&lt;/span&gt;&lt;/th&gt;
            &lt;th onClick={() =&gt; dCycle(dState)}&gt;{headers[1]} &lt;span&gt;&lt;FontAwesomeIcon fixedWidth transform=&quot;shrink-3&quot; icon={dState === &#39;default&#39; ? faSort : dState === &#39;asc&#39; ? faSortUp : faSortDown} /&gt;&lt;/span&gt;&lt;/th&gt;
            &lt;th onClick={() =&gt; rCycle(rState)}&gt;{headers[2]} &lt;span&gt;&lt;FontAwesomeIcon fixedWidth transform=&quot;shrink-3&quot; icon={rState === &#39;default&#39; ? faSort : rState === &#39;asc&#39; ? faSortUp : faSortDown} /&gt;&lt;/span&gt;&lt;/th&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
           {Object.values(ratings).filter(o =&gt; o.points.length).map((item) =&gt; {
                return (
                  &lt;tr key={uuidv4()}&gt;
                    &lt;td className=&quot;variant&quot;&gt;{item.name}&lt;/td&gt;
                    &lt;td className=&#39;date&#39;&gt;{item.points.at(-1)[1] + 1 + &quot;/&quot; + item.points.at(-1)[2] + &quot;/&quot; + item.points.at(-1)[0].toString().slice(2, 4) }&lt;/td&gt;
                    &lt;td className=&#39;rating&#39;&gt;{item.points.at(-1)[3]}&lt;/td&gt;
                  &lt;/tr&gt;
                )
           }) ?? null}
        &lt;/tbody&gt;
      &lt;/table&gt;
    &lt;/div&gt;
  );
}

// const displayInfo = () =&gt; (
  
// )

export default Recent;

it keeps refreshing all the trs and tds
how can i fix this

import &#39;./App.css&#39;;
import Recent from &#39;./components/Recent&#39;;

function App() {
  return (
    &lt;Recent /&gt;
  )
}

export default App;

答案1

得分: -1

将 "delete uuidv4() as key" 更改为 "item.name"。

英文:

delete uuidv4() as key and change to item.name

答案2

得分: -1

代码部分不需要翻译,以下是翻译好的部分:

"the code is well and nothing here that would cause re-renders try tracking your code using console.log to see if there is really re-renders and the parent component and check your css file"

"else you can wrap all the tr elements inside a React.memo"

"recent.jsx"

"return (
<table>
<TableRows someData={trProps} />
</table>
)"

"Table rows component:"

"const TableRows = React.memo( ({someData}) => /* Triggers update only if 'someData' changes */
<> { someData.map( data => <tr>{data}</tr> ) } </>
)"

英文:

the code is well and nothing here that would cause re-renders try tracking your code using console.log to see if there is really re-renders and the parent component and check you css file

       {Object.values(ratings).filter(o =&gt; o.points.length).map((item) =&gt; {
           
            console.log(&#39;item.name&#39;);

            return (
              &lt;tr key={uuidv4()}&gt;
                &lt;td className=&quot;variant&quot;&gt;{item.name}&lt;/td&gt;
                &lt;td className=&#39;date&#39;&gt;{item.points.at(-1)[1] + 1 + &quot;/&quot; + item.points.at(-1)[2] + &quot;/&quot; + item.points.at(-1)[0].toString().slice(2, 4) }&lt;/td&gt;
                &lt;td className=&#39;rating&#39;&gt;{item.points.at(-1)[3]}&lt;/td&gt;
              &lt;/tr&gt;
            )
       }) ?? null}

else you can wrap all the tr elements inside a React.memo

recent.jsx

return (
  &lt;table&gt; 
    &lt;TableRows someData={trProps} /&gt;
  &lt;/table&gt;
)

Table rows component:

const TableRows = React.memo( ({someData}) =&gt; /* Triggers update only if &#39;someData&#39; changes */
      &lt;&gt; { someData.map( data =&gt; &lt;tr&gt;{data}&lt;/tr&gt; ) } &lt;/&gt;
    )