Je joue avec des crochets et j'essaie de faire ce qui suit:
import React, { useState, useRef } from 'react';
const EditableField = () => {
const [isEditing, setEditing] = useState(false);
const inputRef = useRef();
const toggleEditing = () => {
setEditing(!isEditing);
if (isEditing) {
inputRef.current.focus();
}
};
return (
<>
{isExpanded && <input ref={inputRef} />}
<button onClick={toggleEditing}>Edit</button>
</>
);
};
Cela va échouer, car current
est nul, car le composant n'a pas encore été rendu, et le champ d'entrée n'est pas encore rendu (et ne peut donc pas être encore concentré).
Quel est le bon moyen de le faire? Je peux utiliser le crochet usePrevious
proposé dans la FAQ React Hooks), mais cela semble être une solution pénible.
Existe-t-il une manière différente?
Vous pouvez utiliser le hook useEffect
pour exécuter une fonction après chaque rendu lorsque isEditing
a changé. Dans cette fonction, vous pouvez vérifier si isEditing
est true
et concentrer l'entrée.
Exemple
const { useState, useRef, useEffect } = React;
const EditableField = () => {
const [isEditing, setEditing] = useState(false);
const toggleEditing = () => {
setEditing(!isEditing);
};
const inputRef = useRef(null);
useEffect(() => {
if (isEditing) {
inputRef.current.focus();
}
}, [isEditing]);
return (
<div>
{isEditing && <input ref={inputRef} />}
<button onClick={toggleEditing}>Edit</button>
</div>
);
};
ReactDOM.render(<EditableField />, document.getElementById("root"));
<script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
<div id="root"></div>