web-dev-qa-db-fra.com

Gérer une entrée avec React hooks

J'ai trouvé qu'il existe plusieurs façons de gérer la saisie de texte de l'utilisateur avec des crochets. Quelle est la manière la plus préférable ou la plus appropriée de gérer une entrée avec des crochets? Lequel utiliseriez-vous?

1) Le crochet le plus simple pour gérer l'entrée, mais plus de champs que vous avez, plus de code répétitif que vous devez écrire.

const [username, setUsername] = useState('');
const [password, setPassword] = useState('');

événements:

onChange={event => setPassword(event.target.value)}
onChange={event => setUsername(event.target.value)}

2) Similaire à l'exemple ci-dessus, mais avec un nom de clé dynamique

const [inputValues, setInputValues] = useState({
  username: '', password: ''
});

const handleOnChange = event => {
  const { name, value } = event.target;
  setInputValues({ ...inputValues, [name]: value });
};

un événement:

onChange={handleOnChange}

3) Une alternative à useState, et comme indiqué sur les documents ReactJS, useReducer est généralement préférable à useState.

const [inputValues, setInputValues] = useReducer(
  (state, newState) => ({ ...state, ...newState }),
  {username: '', password: ''}
);

const handleOnChange = event => {
  const { name, value } = event.target;
  setInputValues({ [name]: value });
};

un événement:

onChange={handleOnChange}

4) useCallback renverra une version mémorisée du rappel qui ne change que si l'une des dépendances a changé.

const [inputValues, setInputValues] = useState({ 
  username: '', password: '' 
});

const handleOnChange = useCallback(event => {
  const { name, value } = event.target;
  setInputValues({ ...inputValues, [name]: value });
});

un événement:

onChange={handleOnChange}
30
ligowsky

Voici comment je le fais (en supposant que vos entrées doivent être à l'intérieur d'un formulaire):

J'ai un composant BasicForm que j'utilise.

Il stocke tous les états des entrées dans un objet dans un seul appel useState ().

Il passe par useContext() l'état inputs avec une fonction onChange() et une fonction setInputInitialState() pour que les entrées définissent leur état initial lorsqu'elles sont d'abord monté. Il passe également sur Focus, onBlur, et il a des fonctions pour valider les champs que je ne montre pas ici pour simplifier le code.

De cette façon, je peux facilement créer un formulaire avec autant d'entrées que je veux, comme:

<BasicForm
      isSubmitting={props.isSubmitting}
      submitAction={ (formState) =>
        props.doSignIn(formState) }
    >
      <TextInput
        type='email'
        label='Email'
        name='email'
        placeholder='Enter email...'
        required
      />
      <TextInput
        type='password'
        label='Password'
        name='password'
        placeholder='Enter password...'
        min={6}
        max={12}
        required
      />
      <SubmitButton
        label='Login'
      />
    </BasicForm>

BasicForm.js

import FormContext from './Parts/FormContext';

function BasicForm(props) {

  const [inputs, setInputs] = useState({});

  function onChange(event) {
    const newValue = event.target.value;
    const inputName = event.target.name;
    setInputs((prevState)=> {
      return({
        ...prevState,
        [inputName]: {
          ...prevState[inputName],
          value: newValue,
          dirty: true
        }
      });
    });
  }

  function setInputInitialState(
    inputName,
    label='This field ',
    type,
    initialValue = '',
    min = false,
    max = false,
    required = false) {

    const INITIAL_INPUT_STATE = {
      label: label,
      type: type,
      onFocus: false,
      touched: false,
      dirty: false,
      valid: false,
      invalid: false,
      invalidMsg: null,
      value: initialValue,
      min: min,
      max: max,
      required: required
    };

    setInputs((prevState) => {
      if (inputName in prevState) {
        return prevState;
      }
      return({
        ...prevState,
        [inputName]: INITIAL_INPUT_STATE
      });
    });

  }

return(
    <FormContext.Provider value={{
      onChange: onChange,
      inputs: inputs,
      setInputInitialState: setInputInitialState,
    }}>
      <form onSubmit={onSubmit} method='POST' noValidate>
        {props.children}
      </form>
    </FormContext.Provider>
  );
}

TextInput.js

L'entrée utilise le crochet useEffect() pour définir leur état initial lorsqu'ils sont montés.

function TextInput(props) {

  const formContext = useContext(FormContext);

  useEffect(() => {
    console.log('TextInput useEffect...');
    formContext.setInputInitialState(
      props.name,
      props.label,
      props.type,
      props.initialValue,
      props.min,
      props.max,
      props.required
    );
  },[]);

  return(
      <input
        type={props.type}
        id={props.name}
        name={props.name}
        placeholder={props.placeholder}
        value={([props.name] in formContext.inputs) ?
                  formContext.inputs[props.name].value
                : props.initialValue || ''}
        onChange={formContext.onChange}
        onFocus={formContext.onFocus}
        onBlur={formContext.onBlur}
      >
      </input>
      </div>
      {([props.name] in formContext.inputs) ?
          formContext.inputs[props.name].invalidMsg && <div><span> {formContext.inputs[props.name].invalidMsg}</span></div>
        : null}
    </div>
  );

...
}
0
cbdeveloper
function App2(){
    const [name, setName] = useState("");
    const [istrue, Setistrue] = useState(false);
    const [lastname,setLastname]=useState("");

    function handleclick(){

       Setistrue(true);
    }

    return(
        <div>
            {istrue ? <div> <h1>{name} {lastname}</h1> </div> : 
            <div>
                <input type="text" placeholder="firstname" name="name" onChange={e =>setName(e.target.value)}/>
                <input type="text" placeholder="lastname" name="lastname" onChange={e =>setLastname(e.target.value)}/>
               <button  type="submit" onClick={handleclick}>submit</button>
            </div>}
        </div>
    )

function App2(){
    const [name, setName] = useState("");
    const [istrue, Setistrue] = useState(false);
    const [lastname,setLastname]=useState("");

    function handleclick(){
       Setistrue(true);
    }

    return(
        <div>
            {istrue ? <div> <h1>{name} {lastname}</h1> </div> : 
            <div>
                <input type="text" placeholder="firstname" name="name" onChange={e =>setName(e.target.value)}/>
                <input type="text" placeholder="lastname" name="lastname" onChange={e =>setLastname(e.target.value)}/>
               <button  type="submit" onClick={handleclick}>submit</button>
            </div>}
        </div>
    )

    }

}
0
user12857235

Voici comment j'utilise en ce moment:

  const [inputValue, setInputValue] = React.useState("");

      const onChangeHandler = event => {
        setInputValue(event.target.value);
      };

      <input
        type="text"
        name="name"
        onChange={onChangeHandler}
        value={inputValue}
      />
0
ncesar