#javascript #html #css #reactjs #react-native
Вопрос:
Я зашел на официальный сайт reactjs и нашел это
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
Если я заменяю
componentDidMount() {
window.addEventListener('keydown', this.keypressed);
}
с этим
useEffect(() => {
window.addEventListener('keydown', keypressed);
},[]);
это должно быть проблемой, верно?
Но когда я использую useEffect и очень быстро нажимаю клавишу, это нарушает сайт, чего не происходит в компонентах, основанных на классах.
Это мой код компонента на основе классов, который работает нормально и не нарушает работу сайта
/* eslint-disable eqeqeq */
import React, { Component } from 'react';
import data from './content/data';
import List from './List';
import Image from './Image';
import '../style/App.sass';
export class App extends Component {
state = {
currentIndex: 0,
};
componentDidMount() {
window.addEventListener('keydown', this.keypressed);
}
keypressed = (e) => {
let { currentIndex } = this.state;
if (e.keyCode == '38' || e.keyCode == '40') e.preventDefault();
if (e.keyCode == '38') {
this.setState({
currentIndex: (currentIndex - 1 data.length) % data.length,
});
}
if (e.keyCode == '40') {
this.setState({
currentIndex: (currentIndex 1) % data.length,
});
}
};
sendIndex = (i) =>
this.setState({
currentIndex: i,
});
render() {
return (
<div className="container0">
<List
currentIndex={this.state.currentIndex}
sendIndex={this.sendIndex}
/>
<Image currentIndex={this.state.currentIndex} />
</div>
);
}
}
export default App;
Это мой функциональный код компонента
/* eslint-disable eqeqeq */
import React, { useState, useEffect } from 'react';
import data from './content/data';
import List from './List';
import Image from './Image';
import '../style/App.sass';
const App = () => {
const [currentIndex, setCurrentIndex] = useState(0);
const keypressed = (e) => {
if (e.keyCode == '38' || e.keyCode == '40') e.preventDefault();
if (e.keyCode == '38')
setCurrentIndex((currentIndex - 1 data.length) % data.length);
if (e.keyCode == '40')
setCurrentIndex((currentIndex 1) % data.length);
};
const sendIndex = (i) => setCurrentIndex(i);
// window.addEventListener('keydown', keypressed);
useEffect(() => {
window.addEventListener('keydown', keypressed);
}, []);
return (
<div className="container0">
<List currentIndex={currentIndex} sendIndex={sendIndex} />
<Image currentIndex={currentIndex} />
</div>
);
};
export default App;
Пожалуйста, скажите мне, что я делаю не так.
Комментарии:
1. Вы получаете какие-либо ошибки в консоли браузера?
2. @Kundansingchouhan Нет, я не получаю никаких ошибок
Ответ №1:
По неизвестной причине вы отключили eslint
функции errors ( /* eslint-disable */
), с их помощью вам будет предложено исправить закрытие на заблокированном значении currentIndex
состояния.
Возможное исправление-передача обратного useState
вызова сеттеру:
const App = () => {
const [currentIndex, setCurrentIndex] = useState(0);
const sendIndex = (i) => setCurrentIndex(i);
useEffect(() => {
const keypressed = (e) => {
if (e.keyCode == "38" || e.keyCode == "40") e.preventDefault();
if (e.keyCode == "38")
setCurrentIndex(
(prevIndex) => (prevIndex - 1 data.length) % data.length
);
if (e.keyCode == "40")
setCurrentIndex((prevIndex) => (prevIndex 1) % data.length);
};
window.addEventListener("keydown", keypressed);
}, []);
return (
<div className="container0">
<List currentIndex={currentIndex} sendIndex={sendIndex} />
<Image currentIndex={currentIndex} />
</div>
);
};