在创建一个用于学习目的的小项目时,我遇到了更新输入值的问题。这是组件(我已尝试将其减少到最低限度)。
function TipSelector({selections, onTipChanged}: {selections: TipSelectorItem[], onTipChanged?:(tipPercent:number)=>void}) {
const [controls, setControls] = useState<any>([]);
const [tip, setTip] = useState<string>("0");
function customTipChanged(percent: string) {
setTip(percent);
}
//Build controls
function buildControls()
{
let controlList: any[] = [];
controlList.push(<input className={styles.input} value={tip.toString()} onChange={(event)=> {customTipChanged(event.target.value)}}></input>);
setControls(controlList);
}
useEffect(()=>{
console.log("TipSelector: useEffect");
buildControls();
return ()=> {
console.log("unmounts");
}
},[])
console.log("TipSelector: Render -> "+tip);
return (
<div className={styles.tipSelector}>
<span className={globalStyles.label}>Select Tip %</span>
<div className={styles.btnContainer}>
{
controls
}
</div>
</div>
);
}
如果我将输入的创建直接移到 return() 语句中,则值会正确更新。
答案 0 :(得分:2)
我会将您的输入移出该组件,让它们从 TipSelector 中管理自己的状态。
见:
https://codesandbox.io/s/naughty-http-d38w9
例如:
import { useState, useEffect } from "react";
import CustomInput from "./Input";
function TipSelector({ selections, onTipChanged }) {
const [controls, setControls] = useState([]);
//Build controls
function buildControls() {
let controlList = [];
controlList.push(<CustomInput />);
controlList.push(<CustomInput />);
setControls(controlList);
}
useEffect(() => {
buildControls();
return () => {
console.log("unmounts");
};
}, []);
return (
<div>
<span>Select Tip %</span>
<div>{controls}</div>
</div>
);
}
export default TipSelector;
import { useState, useEffect } from "react";
function CustomInput() {
const [tip, setTip] = useState("0");
function customTipChanged(percent) {
setTip(percent);
}
return (
<input
value={tip.toString()}
onChange={(event) => {
customTipChanged(event.target.value);
}}
></input>
);
}
export default CustomInput;
答案 1 :(得分:1)
您只调用 buildControls
一次,其中 <input ...
仅获得一次其值。
每当 React 重新渲染您的组件时(例如因为某些状态发生变化),您的 {controls}
都会告诉 React 使用旧值渲染原始 <input ...
。
我不确定您为什么将控件存储在状态变量中?没有必要,正如你所注意到的,它使事情复杂化了很多。您基本上也需要一个 renderControls()
函数,您可以将 {controls}
替换为。