React-window 失去焦点

发布于 2025-01-14 02:14:52 字数 2441 浏览 2 评论 0原文

我将 react-windowreact-table 一起使用,当我在单元格中输入内容,然后单击另一个单元格时,我必须再次单击才能获取聚焦下一个单元格,以便我可以打字。我认为这与 key 无关 - 这是反应失去焦点的常见情况。几乎可以肯定它与react-window有关。删除它后,问题就消失了。

当我用鼠标滚动时,焦点也会丢失。因此,如果我将注意力集中在一个单元格上,然后用鼠标滚轮滚动,它就会变得模糊。

代码沙箱

import React from 'react'
import { useTable } from 'react-table'
import { FixedSizeList } from 'react-window'

const EditableCell = ({
  value: initialValue,
  row: { index },
  column: { id },
  updateMyData,
}) => {
  const [value, setValue] = React.useState(initialValue)
  const onChange = e => setValue(e.target.value)
  const onBlur = () => updateMyData(index, id, value)
  React.useEffect(() => {setValue(initialValue)}, [initialValue])
  return <input value={value} onChange={onChange} onBlur={onBlur} />
}
const defaultColumn = { Cell: EditableCell,  width: 200,}
function Table({ columns, data, updateMyData }) {
  const table = useTable({columns, data, defaultColumn, updateMyData})

  const RenderRow = React.useCallback( ({ index, style }) => {
      const row = table.rows[index]
      table.prepareRow(row)
      return (
         <tr {...row.getRowProps({ style })} className="tr">
          {row.cells.map(cell =>  (
              <td {...cell.getCellProps()} className="td">
                {cell.render('Cell')}
              </td> ))}
        </tr> )
    }, [table.prepareRow, table.rows])

  return (
      <table {...table.getTableProps()}>
        <tbody {...table.getTableBodyProps()}>
        <FixedSizeList
          height={400}
          itemCount={table.rows.length}
          itemSize={35}
          width={table.totalColumnsWidth}
        >
          {RenderRow}
        </FixedSizeList>
        </tbody>
      </table>
  )
}

function App() {
  const columns = React.useMemo(
    () => [
          {Header: 'Name',accessor: 'name',},
        ],
    []
  )

  const [data, setData] = React.useState(() => {return Array(1000).fill({name:'Jack'})})

  const updateMyData = (rowIndex, columnId, value) => {
    const temp = [...data]
    temp[rowIndex]={...temp[rowIndex],[columnId]:value}
    setData(temp)
  }

  return ( <Table columns={columns} data={data} updateMyData={updateMyData} /> )
}

export default App

I'm using react-window together with react-table and when I type something in a cell, an then click on another cell, I have to click again to get the next cell focused so I can type. I don't think it has to do with key - the usual case of react loosing focus. Almost sure it has to do with react-window. When removing it, the issue is gone.

Focus is also being lost when I scroll with the mouse. So if I'm focused in a cell, and then scroll with the mouse wheel, it blures.

Code Sandbox:

import React from 'react'
import { useTable } from 'react-table'
import { FixedSizeList } from 'react-window'

const EditableCell = ({
  value: initialValue,
  row: { index },
  column: { id },
  updateMyData,
}) => {
  const [value, setValue] = React.useState(initialValue)
  const onChange = e => setValue(e.target.value)
  const onBlur = () => updateMyData(index, id, value)
  React.useEffect(() => {setValue(initialValue)}, [initialValue])
  return <input value={value} onChange={onChange} onBlur={onBlur} />
}
const defaultColumn = { Cell: EditableCell,  width: 200,}
function Table({ columns, data, updateMyData }) {
  const table = useTable({columns, data, defaultColumn, updateMyData})

  const RenderRow = React.useCallback( ({ index, style }) => {
      const row = table.rows[index]
      table.prepareRow(row)
      return (
         <tr {...row.getRowProps({ style })} className="tr">
          {row.cells.map(cell =>  (
              <td {...cell.getCellProps()} className="td">
                {cell.render('Cell')}
              </td> ))}
        </tr> )
    }, [table.prepareRow, table.rows])

  return (
      <table {...table.getTableProps()}>
        <tbody {...table.getTableBodyProps()}>
        <FixedSizeList
          height={400}
          itemCount={table.rows.length}
          itemSize={35}
          width={table.totalColumnsWidth}
        >
          {RenderRow}
        </FixedSizeList>
        </tbody>
      </table>
  )
}

function App() {
  const columns = React.useMemo(
    () => [
          {Header: 'Name',accessor: 'name',},
        ],
    []
  )

  const [data, setData] = React.useState(() => {return Array(1000).fill({name:'Jack'})})

  const updateMyData = (rowIndex, columnId, value) => {
    const temp = [...data]
    temp[rowIndex]={...temp[rowIndex],[columnId]:value}
    setData(temp)
  }

  return ( <Table columns={columns} data={data} updateMyData={updateMyData} /> )
}

export default App

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

饭团 2025-01-21 02:14:52

通过在 Table 组件外部声明 RenderItem 组件来修复。因此组件没有重新声明,只是更新了 props。 (建议永远不要在父组件中声明子组件)

代码沙箱

import React from 'react'
import { useTable } from 'react-table'
import { FixedSizeList } from 'react-window'

const RenderRow = ({ index, style,data:{table} }) => {
  const row = table.rows[index]
  table.prepareRow(row)
  return (
     <tr {...row.getRowProps({ style })} className="tr">
      {row.cells.map(cell =>  (
          <td {...cell.getCellProps()} className="td">
            {cell.render('Cell')}
          </td> ))}
    </tr> )
}

const EditableCell = ({
  value: initialValue,
  row: { index },
  column: { id },
  updateMyData,
}) => {
  const [value, setValue] = React.useState(initialValue)
  const onChange = e => setValue(e.target.value)
  const onBlur = () => updateMyData(index, id, value)
  React.useEffect(() => {setValue(initialValue)}, [initialValue])
  return <input value={value} onChange={onChange} onBlur={onBlur} />
}
const defaultColumn = { Cell: EditableCell,  width: 200,}
function Table({ columns, data, updateMyData }) {
  const table = useTable({columns, data, defaultColumn, updateMyData})



  return (
      <table {...table.getTableProps()}>
        <tbody {...table.getTableBodyProps()}>
        <FixedSizeList
          height={400}
          itemData={{table}}
          itemCount={table.rows.length}
          itemSize={35}
          width={table.totalColumnsWidth}
        >
          {RenderRow}
        </FixedSizeList>
        </tbody>
      </table>
  )
}

function App() {
  const columns = React.useMemo(
    () => [
          {Header: 'Name',accessor: 'name',},
          {Header: 'Age',accessor: 'age',},
        ],
    []
  )

  const [data, setData] = React.useState(() => {return Array(1000).fill({name:'Jack'})})

  const updateMyData = (rowIndex, columnId, value) => {
    const temp = [...data]
    temp[rowIndex]={...temp[rowIndex],[columnId]:value}
    setData(temp)
  }

  return ( <Table columns={columns} data={data} updateMyData={updateMyData} /> )
}

export default App

Fixed by declaring the RenderItem component outside of the Table Component. So the component is not re-declared, but just the props are updating. (As recomended never to have child components declared inside Parent component)

Code Sandbox

import React from 'react'
import { useTable } from 'react-table'
import { FixedSizeList } from 'react-window'

const RenderRow = ({ index, style,data:{table} }) => {
  const row = table.rows[index]
  table.prepareRow(row)
  return (
     <tr {...row.getRowProps({ style })} className="tr">
      {row.cells.map(cell =>  (
          <td {...cell.getCellProps()} className="td">
            {cell.render('Cell')}
          </td> ))}
    </tr> )
}

const EditableCell = ({
  value: initialValue,
  row: { index },
  column: { id },
  updateMyData,
}) => {
  const [value, setValue] = React.useState(initialValue)
  const onChange = e => setValue(e.target.value)
  const onBlur = () => updateMyData(index, id, value)
  React.useEffect(() => {setValue(initialValue)}, [initialValue])
  return <input value={value} onChange={onChange} onBlur={onBlur} />
}
const defaultColumn = { Cell: EditableCell,  width: 200,}
function Table({ columns, data, updateMyData }) {
  const table = useTable({columns, data, defaultColumn, updateMyData})



  return (
      <table {...table.getTableProps()}>
        <tbody {...table.getTableBodyProps()}>
        <FixedSizeList
          height={400}
          itemData={{table}}
          itemCount={table.rows.length}
          itemSize={35}
          width={table.totalColumnsWidth}
        >
          {RenderRow}
        </FixedSizeList>
        </tbody>
      </table>
  )
}

function App() {
  const columns = React.useMemo(
    () => [
          {Header: 'Name',accessor: 'name',},
          {Header: 'Age',accessor: 'age',},
        ],
    []
  )

  const [data, setData] = React.useState(() => {return Array(1000).fill({name:'Jack'})})

  const updateMyData = (rowIndex, columnId, value) => {
    const temp = [...data]
    temp[rowIndex]={...temp[rowIndex],[columnId]:value}
    setData(temp)
  }

  return ( <Table columns={columns} data={data} updateMyData={updateMyData} /> )
}

export default App
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文