onBlur function on a textbox that rerenders the wh

2019-08-27 15:18发布

问题:

function handleBlur(event) {
  if (event.target.value !== props.value) {
    // a hook function that ends up rerendering the whole playlist
  }
}

i'm experimenting with React hooks and i have a playlist that holds a bunch of components that have input textboxes. modifying an item in the list unfortunately seems to render the whole playlist component despite memoizing so I'm trying to move the save playlist function to onBlur instead of onChange. but when I'm on a textbox and I tab over, once the re-render happens I lose the tab focus of the textbox I'm on. Is there any way I can prevent this? Any tips on how to prevent rerendering the whole playlist when i want to modify just an object in a list would be nice as well

playerList.map((player, index) => (
  <DraftPlayer
     arrayPosition={index}
     key={index + (Math.random()).toString()}
     modifyPlayer={modifyPlayer}  //hook function
     player={player}
   />
 ))

const [playerList, setPlayerList] = React.useState(
    initializePlayerListArray([ { firstName: "", lastName: "" },{ firstName: "", lastName: "" },{ firstName: "", lastName: "" },{ firstName: "", lastName: "" },{ firstName: "", lastName: "" },etc ])
  );

回答1:

The issue you are experiencing is because you are setting a random key on every render cycle. React uses the key for rendering performance, however when that key is randomized its telling react a new item is being rendered, or that it should be. In turn the input is essentially unmounted then remounted in the DOM. This is why you end up losing focus. Instead you should try to keep the key as constant as possible (relevant to the item that is being rendered).

I don't know the player model you are working with, but so were on the same page I'm going to write a typescript interface for the Player :)

interface Player {
  id: number
  firstname: string
  lastname: string
  /* ... etc */
}

Then I would create your items this way

playerList.map((player, index) => (
  <DraftPlayer
     arrayPosition={index}
     key={player.id}
     modifyPlayer={modifyPlayer}  //hook function
     player={player}
   />
))