Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

247
Vistas
React-Redux: ¿Cuál es la forma canónica de vincular una acción de pulsación de tecla para iniciar una secuencia reductora?

Esta es una pregunta de novato para react-redux. Pasé un par de horas buscando antes de encontrarla, así que publicaré la pregunta y luego la responderé para la posteridad y también quizás la revisión del código.

Estoy usando react-redux para crear un juego en el que quiero usar las teclas WASD para mover un personaje por un mapa pequeño. (Este es solo un ejemplo de práctica para un esfuerzo mayor). El mapa consiste simplemente en un montón de <div> de colores.

Según tengo entendido, necesito vincular de alguna manera el evento de pulsación de tecla a algo en React DOM para activar mapDispatchToProps y luego iniciar la reevaluación de los reductores. El problema es que, al ser una pulsación de tecla, no hay nada a lo que vincularse. Estoy usando jquery para vincular la pulsación de tecla y llamar a la función.

Consultas relacionadas:

  • Reaccionar: detecte la pulsación de la tecla 'enter' en el evento de cambio, este no es útil porque solo se vincula al evento onChange de un área de texto
  • https://facebook.github.io/react/docs/events.html#keyboard-events no te dice cómo enlazar y, de hecho, ¡realmente no pude entender cómo usar onKeyDown con un elemento! extraño.
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Básicamente, puede desencadenar una acción en un controlador de eventos de keypress de tecla

 class App extends React.Component { constructor() { super(); this.handleKeyPress = this.handleKeyPress.bind(this); } handleKeyPress(event) { // you may also add a filter here to skip keys, that do not have an effect for your app this.props.keyPressAction(event.keyCode); } componentDidMount() { document.addEventListener('keypress', this.handleKeyPress); } componentWillUnmount() { document.removeEventListener('keypress', this.handleKeyPress); } render() { return <div>Your game content</div>; } } export default connect(mapStateToProps, {keyPressAction})(App)

handleKeyPress llama al creador de la acción, que empujará la acción a los reductores.

over 4 years ago · Santiago Trujillo Denunciar

0

Para aquellos que usan redux más nuevos en mecanografiado con clases funcionales, probablemente quieran algo como esto:

 import { useDispatch } from "react-redux"; import { useEffect } from "react"; const App = () => { const dispatch = useDispatch(); useEffect(() => { document.addEventListener('keydown', handleKeyDown); document.addEventListener('keyup', handleKeyUp); return function cleanup() { document.removeEventListener('keydown', handleKeyDown); document.removeEventListener('keyup', handleKeyUp); }; }); const handleKeyDown = (event) => { console.debug("Key event", event); dispatch(handleKeyInput(game_state, connection_status, event.key)); document.removeEventListener('keydown', handleKeyDown); }; const handleKeyUp = (event) => { document.addEventListener('keydown', handleKeyDown, {once: true}); }; }

Consulte https://reactjs.org/docs/hooks-effect.html .

over 4 years ago · Santiago Trujillo Denunciar

0

La solución fue adaptada de aquí:

addEventListener reacciona redux con despacho mapeado

la clave es soltar el jquery y vincularlo DENTRO del componente de reacción usando document.addEventListener. aquí está el extracto del código de trabajo:

 //////////////////////////////////////////// ////////////////////// containers //////////////////////////////////////////// class GameMap extends React.Component{ renderMap(){ console.log('renderMap') console.log(this.props) return this.props.gamemap.map((tile) => { //const x = "tile " + tile return <div className={"tile " + tile}></div> }) } render() { console.log('GameMap.render()') return ( <div className="GameMap"> {this.renderMap()} </div>) } componentDidMount() { console.log("componentDidMount") console.log(this) // the following line won't be bound to the store here... document.addEventListener("keydown", this.props.keyPress ); } } function GMmapStateToProps(state){ //from here goes into this.props console.log('BLmapStateToProps') console.log(state) const gamemap = state.gamemap.gamemap.map((a) => { switch (a){ case 1: return "tile-free" case 9: return "tile-user" } return "tile-wall" }) return{ gamemap: gamemap } } function GMmapDispatchToProps(dispatch){ //when selectbook called, pass result to all reducers console.log('GMmapDispatchToProps') return bindActionCreators({keyPress: keyPress}, dispatch) } const VGameMap = connect(GMmapStateToProps, GMmapDispatchToProps)(GameMap) //////////////////////////////////////////// ////////////////////// actions //////////////////////////////////////////// // actions/index.js action creator function keyPress(key) { console.log('keyPress: ', key) console.log(key.key) var vector = "" switch(key){ case 'w', 'ArrowUp': vector = {x:0,y:1} case 's', 'ArrowDown': vector = {x:0,y:-1} case 'a', 'ArrowLeft': vector = {x:-1,y:0} case 'd', 'ArrowRight': vector = {x:1,y:0} } return { type: "KEYPRESS", payload: vector } // this is an action created }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda