web-dev-qa-db-fra.com

Comment concentrer quelque chose sur le prochain rendu avec React Hooks

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?

11
Kris Selbekk

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>
21
Tholle