我有一个react组件,它有多种选择。我为每一个选择关联了一条快捷方式。为此,我使用";反应热键挂钩";。
所以第一个答案有捷径1,第二个答案有答案2,依此类推
问题是,在回答后,我更新了视图,以显示另一个可以有不同数量选择的问题。这会导致钩子爆炸,因为钩子的数量因渲染而异。
// sort of pseudo-code
const comp = () => {
for(let i=1; i < 6; i++) {
useHotKey(i, callback, [dependencies])
}
return (
<>
<choice/>
<choice/>
</>
)
}
我将如何着手实施这一点?目前我只默认创建5个快捷键,但我希望键盘快捷键的数量不要硬编码。
也许以下示例可以帮助您:
const useHotKey = (keys, callback) => {
React.useEffect(() => {
const keyUp = (e) => {
if (keys.includes(e.key)) {
callback(e.key);
}
};
document.body.addEventListener('keyup', keyUp);
return () =>
document.body.removeEventListener('keyup', keyUp);
}, [callback, keys]); //callback never chanes but keys does
};
const questions = [
['1', '2', '3', '4'],
['1', '2'],
['1', '2', '3'],
['a', 'b', 'c'],
];
const Answer = ({ answers, answer }) => {
useHotKey(answers, answer);
return <pre>ansers:{JSON.stringify(answers)}</pre>;
};
const App = () => {
const [current, setCurrent] = React.useState(0);
const [answers, setAnswers] = React.useState([]);
//answer is the callback but never changes because
// there are no dependencies
const answer = React.useCallback((answer) => {
setAnswers((answers) => [...answers, answer]);
setCurrent((current) => current + 1);
}, []); //no dependencies, answers only created on mount
return current < questions.length ? (
<Answer answers={questions[current]} answer={answer} />
) : (
<pre>
answers given:{JSON.stringify(answers, undefined, 2)}
</pre>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
由于钩子规则的原因,不能动态调用钩子,更好的方法是使用组合。
您的Choice
组件应该有一个hotKey
和callback
道具,父组件应该指定选择的数量。
const Choice = ({ hotKey, callback }) => {
useHotKey(hotKey, callback);
return <>...</>;
};
// Usages
<Choice hotKey="1" callback={()=>console.log('1')} />
choices.map((_,index) => <Choice key={index} hotKey={index} ... />);
请参阅React中的Thinking和HMR的代码示例。