我有多行,每行包含两个文本输入和一个按钮。当用户关注其中一个输入时,应该显示按钮。当元素失去焦点时,按钮应该再次变得不可见。我最好的尝试:
const Input = ({inputRef}) => {
return (
<>
<h1>Input</h1>
<input type="text" ref={inputRef}/>
</>
)
}
export default () => {
const firstRef = useRef(null);
const secondRef = useRef(null);
const it = useRef(null);
const [editing, setEditing] = useState(false);
function handleClick(e) {
firstRef.current.focus();
}
function handleSave() {
console.log("saving!");
}
function checkFocus(e) {
if (!it.current.contains(document.activeElement)) {
setEditing(false);
} else {
setEditing(true);
}
}
useEffect(() => {
document.body.addEventListener("focus", checkFocus, true);
return () => {
document.body.removeEventListener("focus", checkFocus, true);
}
}, []);
return (
<div ref={it}>
<Input inputRef={firstRef}/>
<Input inputRef={secondRef}/>
<button type="button" onClick={handleSave} style={{visibility: editing ? "visible" : "hidden"}}>Save</button>
<button type="button" onClick={handleClick}>Edit</button>
</div>
)
}
是否有更好/更优雅和有效的方法来实现这一点?
这里有一个解决方案,您正在尝试只使用CSS,在我看来,这使它更优雅(和稍微更好的性能,但实际上这是微不足道的)。
https://codepen.io/danny_does_stuff/pen/QWMprMJ
<div>
<input id="input1" />
<input id="input2" />
<button id="save-button">Save</button>
<button id="edit-button">Edit</button>
</div>
<style>
input#input2:focus + button#save-button {
visibility: hidden;
}
</style>
如果你想用更React的方式来做,你可以按照Marco B在他的回答中建议的去做
您可以使用onBlur
和onFocus
事件
这应该像预期的那样工作,只需调整组件上的逻辑
编辑
编辑onBlur方法。
const INITIAL_STATE = {
input: ''
}
export default function App() {
const [show, setShow] = useState(false);
const [value, setValue] = useState(INITIAL_STATE);
const handleChange = (e) => {
const { value, name } = e.target;
setValue(prevState => ({ ...prevState, [name]: value }))
}
const onBlur = () => {
if (!value.input) {
setShow(false)
}
}
return (
<>
<Input name="input" onChange={handleChange} value={value.input} onFocus={() => setShow(true)} onBlur={onBlur} />
{show && <button>TEST</button>}
</>
);
}
const Input = (props) => {
return (
<>
<h1>Input</h1>
<input {...props} type="text" />
</>
);
};