Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

248
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!