Fermer

septembre 22, 2022

Comment lier n’importe quel composant aux données dans React : liaison à sens unique


Cet article discutera de la liaison de données, des types, de la façon d’utiliser useState et useRef pour lier des données dans React et plus encore.

La liaison de données est le couplage et la synchronisation de deux sources de données ; lorsque les données changent dans un élément, l’élément lié est mis à jour pour refléter ce changement. La liaison de données est utilisée pour de nombreuses raisons, telles que la liaison de l’interface utilisateur (UI) d’une application aux données qu’elle affiche, pour la saisie de données, etc. Elle permet également à l’utilisateur de l’application de manipuler les données représentées dans les éléments de la page Web sans avoir besoin d’utiliser processus de programmation ou de script compliqués.

Types de liaison de données

Ici, nous aborderons les deux manières de lier des données dans une application.

  • Reliure unidirectionnelle : il s’agit d’un moyen simple d’implémenter la liaison de données. Les consommateurs de données sont automatiquement mis à jour lorsque les données source (fournisseur) changent, mais pas l’inverse.
  • Reliure bidirectionnelle : La liaison bidirectionnelle est l’endroit où les modifications du consommateur de données ou de la source de données (fournisseur) mettent automatiquement à jour l’autre.

Noter: La liaison de données unidirectionnelle est l’architecture que React suit pour le flux de données ; par conséquent, le reste de cet article examinera les différentes manières d’implémenter la liaison de données unidirectionnelle dans React.

Configuration du projet

Avant de passer à la suite de l’article, configurons notre application React. Accédez à votre terminal et entrez les commandes suivantes.

npx create-react-app react-bind-app
cd react-bind-app
npm start

Liaison de données avec useState

Dans la version précédente, les composants de la classe React étaient les seuls composants qui avaient un état, mais à partir de React 16.6+, les composants fonctionnels ont commencé à avoir un état. Pourtant, vous devez utiliser Crochets de réaction pour activer l’état dans les composants fonctionnels. Ici, nous allons utiliser le crochet useState, lié à notre JSX (JavaScript XML), et transmettre nos données en tant qu’accessoires.

Remplacez le code dans votre App.js dossier dans le src/ répertoire avec le code suivant :

import React from "react";

const App = () => {
  const [formField, setFormField] = React.useState({
    username:"", 
    password: ""
  })
  const formFieldHandler = (e)=>{
    let name = e.target.name
    let value = e.target.value
    setFormField({...formField, [name]:value})
  }
  return (
    <form 
      onSubmit={(e)=>{
        e.preventDefault()
        console.log(formField)
      }}
      style={{
        marginTop: 50, 
        display: "flex", 
        flexDirection: "column"
      }}
     
    >
      <input 
        type="text"
        name="username" 
        value={formField.username} 
        onChange={formFieldHandler} 
        placeholder="Username"
        style={{
          padding: "10px 10px", 
          width: "80%", 
          maxWidth: 540, 
          margin: "5px auto"
        }}
      />
      <input 
        type="password" 
        name="password"
        value={formField.password} 
        onChange={formFieldHandler} 
        placeholder="Password"
        style={{
          padding: "10px 10px",
          width: "80%",
          maxWidth: 540,
          margin: "5px auto"
        }}
      />
      <button
        style={{width: 200, padding: 10, margin: "15px auto"}}
      >Submit</button>
    </form>
  );
};
export default App

Dans le code ci-dessus, nous avons affiché une application de formulaire simple pour montrer comment les données sont liées dans React. Nous avons d’abord importé React de react pour nous permettre d’accéder à useState accrocher. Ensuite, nous avons déstructuré le tableau de deux valeurs que nous avons reçu de React.useState dans formField et setFormField. La première valeur est une variable/champ, et la deuxième valeur est une fonction que nous avons utilisée pour mettre à jour la première valeur (variable/champ).

Ensuite, nous avons créé un formFieldHandler; ici, nous avons implémenté la logique de mise à jour du formFieldce qui implique de simplifier les propriétés de l’objet événement.

Dans la section retour du App fonction, nous avons implémenté notre JSX. Dans le formulaire JSX, nous avons passé un onSubmit prop qui empêche le navigateur d’effectuer son action par défaut lorsque le formulaire est soumis.

Ensuite, dans le JSX d’entrée, nous avons lié la valeur props et le onChange accessoires à la formfield properties, rendant l’élément de composant React (App fonction) le fournisseur de données et l’élément React DOM (formulaire et entrée) le consommateur de données. Nous avons également ajouté un accessoire de style pour l’esthétique.

Noter: Dans le formFieldHandlernous avons utilisé la propriété calculée lors de la mise à jour de la formFieldqui implique l’utilisation de l’attribut de nom d’entrée comme formField la propriété name et l’attribut de valeur d’entrée comme formField propriété de valeur (e.target.name, e.target.value). Sans cela, React ne saura pas quelle propriété mettre à jour et vous ne verrez pas la mise à jour dans votre navigateur.

Formulaire de réaction avec des champs pour le nom d'utilisateur et le mot de passe, et un bouton d'envoi

Liaison de données avec useRef

useRef est un crochet React utilisé pour conserver des données entre différents rendus. Réagir useRef est utilisé pour implémenter une liaison de données unidirectionnelle inversée, où le consommateur de données met automatiquement à jour le fournisseur de données. useRef est utilisé lorsque vous voulez que le DOM du navigateur soit la source de vérité et non votre react-dom; cela permet à l’utilisateur d’accéder aux propriétés DOM.

Dans le App.js fichier, remplacez le code par le code ci-dessous.

import React from "react";
const App = () => {
  const appRef = React.useRef()
  const [filesName, setFilesName] = React.useState([])
  const fileUploadHandler = ()=>{
    appRef.current.click()
  }
  return (
    <div style={{margin: "30px auto", width: 450}}>
      <form onSubmit={(e)=>e.preventDefault()}>
        <input 
          type="file" 
          ref={appRef} 
          style={{ display: "none" }} 
          onChange={(e) => {
            let files = e.target.files
            for(let file of files){
              setFilesName((state)=>{
                return [...state, file.name]
              })
            }
          }}
          multiple={true}
        />
        <button 
          onClick={fileUploadHandler} 
          style={{margin: "20px auto", padding: "10px 20px"}}
        >
          upload file
        </button>
      </form>
      {filesName.map(
        (filename, index) => (
          <p key={index}>{filename}</p>
        )
      )}
    </div>
    
  );
};
export default App

Dans le code ci-dessus, nous bornons le appRef propriété actuelle à l’entrée JSX ref attribut pour nous permettre d’accéder aux propriétés DOM du navigateur. Nous avons passé un onChange prop à l’entrée JSX pour nous permettre d’accéder au formFiles données de la propriété des fichiers cibles d’événements et les stocker dans le App état de la fonction (filesName, setFileName).

La fileUploadHandler La fonction est appelée chaque fois que le bouton JSX est cliqué, ce qui déclenche un événement de clic sur l’entrée JSX. Ceci est fait parce que nous avons stylisé l’entrée JSX pour qu’elle soit masquée ; ce n’est pas nécessaire, mais les conceptions modernes, comme le glisser-déposer, nécessitent cette logique.

Noter: La ref L’attribut n’est pas un accessoire React et est géré séparément des accessoires React car il fonctionne dans l’ordre inverse des accessoires.

bouton de téléchargement de fichier

les noms de fichiers s'affichent dans une liste de mp4

ref-hook dans React DevTools

L’image ci-dessus est un instantané de React DevTools ; comme vous pouvez le voir, le ref hook est lié à l’entrée JSX.

Pourquoi devriez-vous utiliser useState plutôt que useRef

Dans React, nous avons deux types de formulaires : un formulaire non contrôlé et un formulaire contrôlé. Un formulaire non contrôlé est un formulaire qui conserve sa source de vérité dans le DOM du navigateur et doit être utilisé dans des cas tels que le téléchargement de fichiers, l’intégration d’une API tierce, etc. Un formulaire contrôlé est un formulaire où l’état du composant React agit comme la source de la verité.

Utilisation useRef chaque fois que la source de vérité doit être le DOM, et utilisez useState lorsque la source de vérité peut être un composant React.

Liaison de données avec useReducer

L’architecture Flux a été très populaire dans React, et Redux a été le précurseur dans l’utilisation de l’architecture Flux pour la gestion des états. Cependant, dans React 16.6+, React a ajouté le useReducer et useContext hooks pour implémenter l’architecture Flux dans les applications React sans utiliser de bibliothèque.

Dans ton src/ répertoire, créer un fichier store.js et collez le code suivant dans le fichier.

export const storeData = {
  submit:false, 
  formField:{username:"", password:""}
}

Dans le code ci-dessus, nous avons créé un objet d’état que nous utiliserons globalement dans toute l’application. Bien que storeData est global à notre application, il est toujours encapsulé, donc seules les parties de notre application que nous exposons au storeData peut le modifier.

Dans ton src/ répertoire, créez un reducer.js fichier et collez le code suivant dans le fichier.

const reducer = (state, action)=>{
  switch(action.type){
  case "SUBMIT":
    return {
      ...state, 
      submit:true, 
      formField:{
        ...state.formField,
        [action.formField.name]:action.formField.value
      } 
    }
  default:
    return state
     
  }
}
export default reducer

Dans le code ci-dessus, nous avons créé un reducer fonction, qui prend deux arguments—l’état de la storeData objet et un action objet envoyé depuis différentes parties de notre application pour initier un changement. Dans le bloc switch, nous avons créé une logique pour gérer le cas où le type d’action est « Soumettre » et pour mettre à jour l’état.

Noter: Mettez toujours en œuvre les reducer fonctionne comme un fonction pure (sans effets secondaires).

Remplacez le code dans votre App.js fichier avec le code ci-dessous.

import React from "react";
import { storeData } from "./store.js";
import Form from "./Form.js";
import reducer from "./reducer.js";


export let AppContext = React.createContext()
AppContext.displayName = "App Context"


const App = () => {
  let [storeDataValue, dispatch] = React.useReducer(reducer, storeData)
  return (
    <AppContext.Provider
      value={{ storeDataValue, dispatch }}
    >
      <Form />
    </AppContext.Provider>
   
  );
};
export default App

Nous avons importé notre reducer fonction, storeData objet et Form composant dans le code ci-dessus.

Ensuite, nous avons créé un AppContext utilisant React.createContextce qui nous permet d’accéder au fournisseur et displayName propriété, qui aide lors du débogage. Dans le App fonction, nous avons déstructuré le tableau de deux à partir de useReducersimilaire à notre implémentation précédente de useState. Enfin, nous rendons notre Form composant (pas encore créé), enveloppé par le AppContext provider, qui prend une valeur prop destinée à être consommée par d’autres parties de notre application.

Dans ton src/ répertoire, créez un Form.js fichier et collez-y le code suivant.

import React from 'react'
import { AppContext } from './App.js'
const Form = () => {
  const {storeDataValue, dispatch} = React.useContext(AppContext)
  const {username, password} = storeDataValue.formField
  const formHandler = (e)=>{
    let {name, value} = e.target
    dispatch({type:"SUBMIT", formField:{name, value}})
  }
  return (
    <form 
      onSubmit={
        (e)=>{
          e.preventDefault()
        }
      }
      style={
        {
          display: "flex",
          flexDirection: "column",
          justifyContent: "space-between",
          width: 400,
          height: 150,
          margin: "30px auto"
        }
      }
    >
      <input 
        type="text" 
        name="username"
        placeholder="username"
        value={username} 
        onChange={formHandler}
        style={
          {
            padding: 10
          }
        }
      />
      <input 
        type="text" 
        name="password"
        placeholder="password"
        value={password} 
        onChange={formHandler}
        style={
          {
            padding: 10
          }
        } 
      />
      <button
        style={
          {
            padding: 15, 
            width: 200,
            margin: "0 auto"
          }
        }
      >Submit</button>
    </form>
  )
}
export default Form

Dans le code ci-dessus, le AppContext a été importé dans le Form.js dossier. Nous avons consommé le storeDataValue objet et dispatch fonction de AppContext utilisant React.useContext (fonctionne comme AppContext.Consumer).

Ensuite, nous avons créé un formHandler qui prend l’objet événement et envoie une action au réducteur, qui mettra à jour notre storeData objet. Ensuite, nous avons lié la valeur prop à storeDataValue.formField nous avons obtenu de notre AppContext.

stocker des données

contexte d'application

Le fournisseur de contexte est affiché ci-dessus en tant que contexte d’application en raison de la displayName propriété que nous avons définie précédemment.

Construire un formulaire déroulant Select

Vous trouverez ci-dessous une application qui illustre un formulaire déroulant sélectionné. Créer un Data.js fichier et collez le code suivant dans le fichier.

const Data = ["Nigeria", "Ghana", "Germany", "France", "Argentina", "Brazil"]
export default Data

Dans le code ci-dessus, nous avons créé un tableau de pays et les avons exportés. Habituellement, des données comme celles-ci sont obtenues à partir de votre point de terminaison d’application ou d’une API tierce.

Dans ton App.js fichier, remplacez le code par ce qui suit.

import React from "react";
import Data from "./Data.js"
const App = () => {
  const [countryState, setCountryState] = React.useState("")
  const countries = [...Data]
  return (
    <form
      style={
        {
          margin:"100px auto",
          width: 200
        }
      } 
    >
      <select 
        value={countryState} 
        onChange={
          (e) => setCountryState(e.target.value)
        }
      >
        {
          countries.map((country, index)=>{
            return(
              <option 
                key={index} 
                value={country}
              >
                {country}
              </option>
            )
          })
        }
      </select>
    </form>
      
   
  );
};
export default App

Dans le code ci-dessus, nous avons créé un état de composant en utilisant React.useState et lié à la valeur et onChange prop du JSX sélectionné. Ensuite, nous avons mappé les pays sur l’accessoire de valeur JSX de l’option afin de pouvoir sélectionner différents pays.

Le champ déroulant du formulaire contient désormais le Nigeria

dropdown-code montre comment nous pouvons définir différentes valeurs pour lister les éléments

Pour voir plus d’exemples de liaison des composants de l’interface utilisateur React aux données, consultez ces démos dans la documentation de la bibliothèque KendoReact : React Multiselect Data Binding et Liaison de données de liste déroulante React.

Conclusion

React utilise un concept de cascade pour fournir des données des éléments parents aux éléments enfants à l’aide d’accessoires, mais cela pourrait entraîner la nécessité d’un forage d’accessoires, où les accessoires sont passés à travers des composants intermédiaires juste pour accéder au composant qui utilise l’accessoire. C’est pourquoi, pour les applications plus importantes, il est conseillé d’utiliser le contexte React et le réducteur pour atténuer le forage d’hélice.




Source link

septembre 22, 2022