useState 变量在 onChange 事件期间不保持其状态
useState variable not holding its state during onChange event
我正在尝试在我的应用程序 window 的弹出窗口中创建一个简单的文本框。为了让用户输入文本,我创建了一个 useState 变量,并在 onChange 事件期间将状态更新为输入的值。然而,它并没有保持它的状态。代码如下:
const App() {
[units, setUnits] = useState('');
[popUpHtml, setPopUpHtml] = useState('');
...
function handleChange(event){
setUnits(event.target.value);
}
const betslip = (team, line) =>
(
<div className='betslip'>
<h1 className="betslip-header">Betslip</h1>
<div >
<table className="betslip-table">
<tr>
<th>Team</th>
<th>Line</th>
<th>Unit(s)</th>
</tr>
<tr >
<td className='betslip-td'>{team}</td>
<td className='betslip-td'>{linePlusMinus(line)}</td>
<td className='betslip-td'>
<div className='unit-div'>
<input type='text' required className='unit-input' value={units} onChange={(event) => handleChange(event)}/>
</div>
</td>
</tr>
</table>
<table className="betslip-table">
<tr>
<th>Risk</th>
<td className='betslip-td'>{units}</td>
</tr>
<tr>
<th>Reward</th>
<td className='betslip-td'>{reward(units, line)}</td>
</tr>
</table>
</div>
</div>
);
function showPopUp(team, line) {
setPopUpHtml(betslip(team, line));
setPopUpStyle('pop-up-container-show');
}
function PopUp() {
return (
<div id="popUp" className={popUpStyle}>
<div className="pop-up-bg"> </div>
<div className="pop-up">
<img className='close-button' src={closeButton} onClick={hidePopUp.bind(null)} />
{popUpHtml}
</div>
</div>
)
}
...
return (
<div className="container">
<PopUp html={<h1>Hello World </h1>} />
)
我正在尝试重新分配标签中的状态
setPopUpHtml(betslip(team, line));
正如您所发现的,在状态中存储 JSX 元素是一种非常容易导致陈旧数据错误的方法。元素中的值将在您设置状态时被锁定,并且永远不会再次更新(除非您使用新元素再次设置状态)。
相反,您的状态应该只是最少的数据片段,您可以从中判断页面上应该有什么。然后在渲染期间使用该数据来选择要显示的元素。在您的情况下,数据片段似乎是 units
(已经是状态变量)、team
和 line
。所以为团队和线路添加两个状态变量:
const [units, setUnits] = useState('');
const [team, setTeam] = useState(null);
const [line, setLine] = useState(null);
然后在 showPopup 函数中将它们设置为 non-null 值:
function showPopup(team, line) {
setTeam(team);
setLine(line);
}
并在渲染时检查它们的存在:
return (
<div id="popUp" className={team && line ? 'pop-up-container-show' : undefined}>
<div className="pop-up-bg"> </div>
<div className="pop-up">
<img className='close-button' src={closeButton} onClick={hidePopUp.bind(null)} />
{team && line && betSlip(team, line)}
</div>
</div>
);
我正在尝试在我的应用程序 window 的弹出窗口中创建一个简单的文本框。为了让用户输入文本,我创建了一个 useState 变量,并在 onChange 事件期间将状态更新为输入的值。然而,它并没有保持它的状态。代码如下:
const App() {
[units, setUnits] = useState('');
[popUpHtml, setPopUpHtml] = useState('');
...
function handleChange(event){
setUnits(event.target.value);
}
const betslip = (team, line) =>
(
<div className='betslip'>
<h1 className="betslip-header">Betslip</h1>
<div >
<table className="betslip-table">
<tr>
<th>Team</th>
<th>Line</th>
<th>Unit(s)</th>
</tr>
<tr >
<td className='betslip-td'>{team}</td>
<td className='betslip-td'>{linePlusMinus(line)}</td>
<td className='betslip-td'>
<div className='unit-div'>
<input type='text' required className='unit-input' value={units} onChange={(event) => handleChange(event)}/>
</div>
</td>
</tr>
</table>
<table className="betslip-table">
<tr>
<th>Risk</th>
<td className='betslip-td'>{units}</td>
</tr>
<tr>
<th>Reward</th>
<td className='betslip-td'>{reward(units, line)}</td>
</tr>
</table>
</div>
</div>
);
function showPopUp(team, line) {
setPopUpHtml(betslip(team, line));
setPopUpStyle('pop-up-container-show');
}
function PopUp() {
return (
<div id="popUp" className={popUpStyle}>
<div className="pop-up-bg"> </div>
<div className="pop-up">
<img className='close-button' src={closeButton} onClick={hidePopUp.bind(null)} />
{popUpHtml}
</div>
</div>
)
}
...
return (
<div className="container">
<PopUp html={<h1>Hello World </h1>} />
)
我正在尝试重新分配标签中的状态
setPopUpHtml(betslip(team, line));
正如您所发现的,在状态中存储 JSX 元素是一种非常容易导致陈旧数据错误的方法。元素中的值将在您设置状态时被锁定,并且永远不会再次更新(除非您使用新元素再次设置状态)。
相反,您的状态应该只是最少的数据片段,您可以从中判断页面上应该有什么。然后在渲染期间使用该数据来选择要显示的元素。在您的情况下,数据片段似乎是 units
(已经是状态变量)、team
和 line
。所以为团队和线路添加两个状态变量:
const [units, setUnits] = useState('');
const [team, setTeam] = useState(null);
const [line, setLine] = useState(null);
然后在 showPopup 函数中将它们设置为 non-null 值:
function showPopup(team, line) {
setTeam(team);
setLine(line);
}
并在渲染时检查它们的存在:
return (
<div id="popUp" className={team && line ? 'pop-up-container-show' : undefined}>
<div className="pop-up-bg"> </div>
<div className="pop-up">
<img className='close-button' src={closeButton} onClick={hidePopUp.bind(null)} />
{team && line && betSlip(team, line)}
</div>
</div>
);