我将类组件重写为功能组件,因为必须使用react钩子。现在,除了屏幕外,其他所有功能都可以正常工作。它不更新文本。我已经添加了一个引用到称为screen element的元素,并且函数setScreenText似乎起作用。我放了一些日志,它们返回了我对它们的期望。如果我按5键,console.log(screenElement.textContent)
返回5,console.log(screenElement)
返回{current: div.screen, textContent: "5"}
唯一的问题仍然是它没有更新屏幕上的文本,因此保持空白。
import React, {useRef, useState} from 'react';
import '../style/App.scss';
import {UPDATE_GAME_STATE} from '../actions';
import { useDispatch } from 'react-redux';
function Keypad() {
const dispatch = useDispatch();
const KEYPAD_STATE_SUCCESS = "keypad_success";
const KEYPAD_STATE_FAILED = "keypad_failed";
const KEYPAD_STATE_INPUT = "keypad_input";
const [state, setState] = useState(KEYPAD_STATE_INPUT);
const tries = [];
const screenElement = useRef(null);
const handleKeyPress = async(value) => {
tries.push(value);
setScreenText(tries.join(''));
if (tries.length >= 4) {
const success = await tryKeyCode(tries.join(''))
const newState = {
setState: success ? KEYPAD_STATE_SUCCESS : KEYPAD_STATE_FAILED
}
const screenText = success ? "SUCCESS" : "FAILED";
const textScreenTime = success ? 3000 : 1000;
const handleGameState = success ? () => onSuccess() : () => onFailed();
setTimeout(() => {
setScreenText(screenText);
setTimeout(handleGameState, textScreenTime);
}, 200);
setState(newState);
}
}
const onSuccess = () => {
dispatch(UPDATE_GAME_STATE('completed'))
}
const onFailed = () => {
console.log("wrong code")
}
/**
* @param {string} text
*/
const setScreenText = (text) => {
screenElement.textContent = text;
console.log(screenElement.textContent); // if key 5 is pressed returns 5
console.log(screenElement); // returns {current: div.screen, textContent: "5"}
}
/**
* @param {string} code
* @returns boolean
*/
const tryKeyCode = async(code) => {
const response = (await fetch("http://localhost:3000/keypad", {
method: "POST",
body: JSON.stringify({
"code": code
}),
headers: {
"Content-Type": "application/json"
}
}));
return response.status === 200;
}
const keys = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const Key = ({number, className = ""}) => <button className={"key " + className} onClick={() => handleKeyPress(number)}>{number}</button>
const keyElements = keys.map(key => (<Key number={key}/>))
return (
<div className="keypad_wrapper">
<div className="screen" ref={screenElement}/>
{keyElements}
<Key className="last" number={0}/>
</div>
);
}
export default Keypad;
答案 0 :(得分:1)
如react docs中所述:
useRef
返回一个可变的ref对象,该对象的.current
属性已初始化为传递的参数(initialValue
)。返回的对象将在组件的整个生命周期中保持不变。
因此,无需更新screenElement.textContent
,而是需要像这样更新screenElement.current.textContent
:
const setScreenText = (text) => {
if (screenElement.current) {
// Wait until current is available
// `current` points to the mounted element
screenElement.current.textContent = text;
console.log(screenElement.current);
}
}