亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如果 props 改變,React.memo 不會重新渲染

如果 props 改變,React.memo 不會重新渲染

守著一只汪 2023-08-10 15:30:42
我正在嘗試使用 React memo 組件作為行從頭開始創建一個 Table 組件,以防止不必要的重新渲染。rows cells 是一個由子函數創建的 React 組件數組,其中包含行數據、行 id、行索引和 commitChange 函數作為參數。commitChange 函數用于設置行的表狀態。這是代碼:表組件.jsxexport const Table = ({ data: initialData, maxRows = 10, children: makeChildren, primaryKey = 'ID' }) => {const [TableData, setTableData] = useState(initialData);console.log('table re-render')useEffect(() => {    console.log('--->table data', TableData)}, [TableData]);useEffect(() => {    setTableData(initialData)}, [initialData]);const renderCells = useCallback((param) => {    return makeChildren(param)}, [])const commitChange = useCallback((field, value, index) => {    setTableData(prevTableData => {        const newState = Array.from(prevTableData)        newState[index][field] = value        return [...newState]    })}, [])const renderRows = () => {    return TableData.map((row, i) =>        <TableRow            key={row[primaryKey]}            index={i}            rowData={row}            cells={renderCells}            id={row[primaryKey]}            updateTableData={commitChange}        />    )}//return (    <table>        <tbody>            {                renderRows()            }        </tbody>    </table>  );}const TableRow = React.memo(({ index, rowData, cells, id, updateTableData }) => {console.log('render row' + index, rowData)useEffect(() => {    console.log('row ' + index + ' data', rowData)}, [rowData])const renderCells = () => {    return cells({ data: rowData, index, id, commitChange: (field, value) => updateTableData(field, value, index) }).map((c, i) => {        return (            <td key={i}>                {c}            </td>        )    })}return (    <tr>        {renderCells()}    </tr>)})當一個元素被添加到 Table 組件上的 data props 時,表會重新渲染并僅渲染添加的行,這樣就可以正常工作。但是,當從第二個單元格中的文本框中編輯行元素時,父表組件上的數據已正確更新,但行未重新呈現。當我使用 React.memo areEqual 函數(此處的文檔)檢查傳遞給組件的上一個和下一個屬性時,數據屬性是相同的。當 TableData 按行更新并且執行 renderRows 函數但不重新渲染更新的行時,表組件將重新渲染。問題是什么?感謝幫助PS 否,我不需要外部庫來制作自定義表格元素
查看完整描述

1 回答

?
ABOUTYOU

TA貢獻1812條經驗 獲得超5個贊

問題是您正在淺復制 TableData (使用...),因此當您更新此處的值時:


newState[index][field] = value

...您正在改變數組中的項目,但對該項目的引用保持不變。一種解決方法是這樣做:


setTableData(prevTableData =>

    prevTableData.map((item, i) =>

      i === index ? { ...item, [field]: value } : item,

    ),

  )

所以現在當字段更新時會創建一個新對象。


查看完整回答
反對 回復 2023-08-10
  • 1 回答
  • 0 關注
  • 216 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號