Ich habe gerade die Hooks-Dokumentation durchgesehen, als ich darauf gestoßen bin useRef
.
Schauen Sie sich ihr Beispiel an…
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
… Es scheint, useRef
als könnte durch ersetzt werden createRef
.
function TextInputWithFocusButton() {
const inputRef = createRef(); // what's the diff?
const onButtonClick = () => {
// `current` points to the mounted text input element
inputRef.current.focus();
};
return (
<>
<input ref={inputRef} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
Warum brauche ich einen Haken für Schiedsrichter? Warum gibt useRef
es?
quelle
useRef
, die von einem der React-Entwickler veröffentlicht wurde. Es ist nicht dasselbe wie einfach anzurufencreateRef
, dacreateRef
es kein Hook ist und keinen Status zwischen Anrufen beibehält. Die Antwort von Ryan Cogswell hat auch ein gutes Beispiel für die Unterschiede.tldr
A
ref
ist ein einfaches JS-Objekt{ current: <some value> }
.React.createRef()
ist eine Fabrik, die einen Schiedsrichter zurückgibt{ current: null }
- ohne Magie .
Die VerwendunguseRef(initValue)
gibt auch einen{ current: initValue }
ähnlichen Ref zurückReact.createRef()
. Außerdem wird dieser Verweis so gespeichert , dass er über mehrere Renderings in einer Funktionskomponente hinweg beständig ist .React.createRef
in Klassenkomponenten ist ausreichend , da das ref-Objekt einer Instanzvariablen zugewiesen ist , auf die über die gesamte Komponente und ihren Lebenszyklus zugegriffen werden kann:this.myRef = React.createRef(); // stores ref in "mutable" this context (class)
useRef(null)
ist im Grunde gleichuseState(React.createRef())[0]
1 .1 Ersetzen Sie
useRef
durchuseState
+createRef
Der folgende Tweet war für mich aufschlussreich:
Mit den Erkenntnissen aus dem
tldr
Abschnitt können wir nun weiter schließen:Der obige Code "missbraucht",
useState
um die zurückgegebene Referenz von beizubehaltenReact.createRef()
.[0]
wählt einfach den Werteteil vonuseState
-[1]
wäre der Setter.useState
bewirkt im Gegensatz zu ein erneutes RendernuseRef
. Genauer gesagt vergleicht React die alte und die neue ObjektreferenzuseState
, wenn ein neuer Wert über seine Setter-Methode festgelegt wird. Wenn wir mutieren den ZustanduseState
direkt ( im Gegensatz zu Setter Aufruf), ihr Verhalten mehr oder weniger wird äquivalent zuuseRef
, da keine Wieder machen mehr ausgelöst wird:// Example of mutaing object contained in useState directly const [ref] = useState({ current: null }) ref.current = 42; // doesn't cause re-render
Hinweis: Tun Sie das nicht! Verwenden Sie die optimierte
useRef
API, anstatt das Rad neu zu erfinden. Oben dient zur Veranschaulichung.quelle
Nur um einen Zweck hervorzuheben:
createRef
ist so einfach wiereturn {current: null}
. Es ist eine Möglichkeit, mitref=
Requisiten auf modernste Weise umzugehen, und das war's auch (während String-basiert zuoo magisch und Callback-basiert zu ausführlich aussieht).useRef
Behält einige Daten vor dem Rendern bei und das Ändern führt nicht zu einem erneuten Rendern (wie dies auch deruseState
Fall ist). Sie sind selten verwandt. Alles, was Sie von einer klassenbasierten Komponente erwarten, die in Instanzfelder (this.* =
) verschoben wird, sieht aus wie ein Kandidat, deruseRef
in funktionale Komponenten implementiert werden soll.Say
useCallback
funktioniert als beschränkte Klassenmethode (this.handleClick = .....bind(this)
) und kann mit neu implementiert werden (aber wir sollten das Rad nicht sicher neu erfinden) mituseRef
.Ein weiteres Beispiel sind DOM-Refs, Timeout- / Intervall-IDs, IDs oder Referenzen von Bibliotheken von Drittanbietern.
PS Ich glaube, das React-Team hat besser unterschiedliche Namen gewählt
useRef
, um Verwechslungen mit zu vermeidencreateRef
. VielleichtuseAndKeep
oder sogarusePermanent
.quelle
Eine weitere, aber wichtige Ergänzung zu den Antworten anderer.
Sie können keinen neuen Wert für festlegen
createRef
. Aber du kannst füruseRef
.const ur = useRef(); const cr = createRef(); ur.current = 10; // you can do it, and value is set cr.current = 10; // you can, but it's no good, it will not change it
quelle
current
Eigenschaft wie gewohnt ändern (gerade getestet). Es spielt keine Rolle, ob der Ref überuseRef
oder erstellt wirdcreateRef
.