1
votes

Pourquoi ne puis-je pas saisir des textes en continu lors de l'utilisation du composant TexInput avec un accessoire

J'essaie de créer un composant TextInput en tant qu'enfant avec une fonction qui provient du composant parent.

mais ensuite, je ne peux pas entrer de texte comme d'habitude (je dois placer le curseur chaque fois que j'entre 1 text)

pourriez-vous me dire comment résoudre ce problème?

merci d'avance.


le composant parent

XXX

le composant enfant

import React, { useState } from "react";
import {
  View,
  StyleSheet,
  Text,
  TouchableOpacity,
  TextInput,
} from "react-native";

export default function TestListInputItem(props) {
  const [count, setCount] = useState(1);

  function handleMakeNew() {
    setCount((v) => v + 1);
  }

  function RenderList() {
    return (
      <View style={styles.list}>
        <TextInput
          style={styles.InputName}
          value={String(props.name)}
          onChangeText={(text) => {
            props.setInputName(text);
          }}
        ></TextInput>
        <TouchableOpacity
          onPress={() => {
            handleMakeNew();
          }}
          style={styles.buttonAdd}
        >
          <Text>Add</Text>
        </TouchableOpacity>
      </View>
    );
  }

  return [...Array(count).keys()].map((i) => <RenderList key={i} />); 
}

const styles = StyleSheet.create({
  list: {
    width: "100%",
    backgroundColor: "#ddd",
    padding: 10,
  },
  InputName: {
    borderWidth: 1,
    height: 40,
    backgroundColor: "#fff",
  },
  buttonAdd: {
    backgroundColor: "orange",
    width: 80,
    height: 40,
    margin: 3,
    justifyContent: "center",
    alignItems: "center",
    alignSelf: "center",
  },
});

Nœud: 12.18.3

React-Native: 4.10.1

Expo: 3.22.3


3 commentaires

c'est probablement parce que vous déstructurez un tableau dans le rendu, ce qui crée un nouveau tableau à chaque fois, donc vous démontez le composant, c'est-à-dire réinitialiser l'état


@Eric Hasselbring, je vois, mais je dois garder ce code return [... Array (count) .keys ()]. ​​Map ((i) => ); en raison d'une spécification de ce projet


Quelle est la spécification qui exigerait cela, est-ce juste pour pouvoir éditer les précédentes?


3 Réponses :


0
votes

C'est ce qu'on appelle le saut de curseur. Pour éviter cela, dans votre composant d'entrée, conservez un état local et utilisez cette valeur d'état comme valeur d'entrée. quand onChange est déclenché, mettez d'abord à jour la valeur de l'état local, puis envoyez-la au composant parent


3 commentaires

bien que j'aie essayé un moyen de le résoudre, je ne pouvais pas ... ça vous dérangerait de me dire un exemple de code pour résoudre le saut de curseur en cas de mon code?


pouvez-vous s'il vous plaît fournir un lien où je peux voir et jouer avec le code?


Je suis désolé, je suis un débutant pour réagir natif donc maintenant je n'ai aucune idée de comment puis-je vous fournir la façon dont vous pourriez jouer le code ...



2
votes

Comme je l'ai commenté, le problème est que votre fonction crée un nouveau tableau sur chaque rendu en réinitialisant votre état, voici une modification rapide qui devrait vous mettre dans la bonne direction

  export default function AddItem(props) {
  return (
    <View style={styles.list}>
      <TextInput
        style={styles.InputName}
        value={props.value}
        onChangeText={(text) => {
          props.setValue(text);
        }}
      ></TextInput>
    </View>
  );
}

export default function TestListInputItem(props) {
  const [list, setList] = useState([]);
  const [value, setValue] = useState("");

  function handleMakeNew() {
    setList((v) => [...v, value]);
  }

  return (
    <View>
      {
        list.map((item, i) => <View key={i}><Text>{item}</Text></View>)
      }
      <AddItem
        value={value}
        setValue={setValue}
      />
      <TouchableOpacity
        onPress={() => {
          handleMakeNew();
        }}
        style={styles.buttonAdd}
      >
        <Text>Add</Text>
      </TouchableOpacity>
    </View>
  )
}


8 commentaires

Bien que j'aie essayé ce code, je dois toujours définir le curseur chaque fois que j'entre 1 texte ...


ok mal éditer le code rapidement, l'autre chose est de réorganiser la structure de votre accessoire, vous ne voudriez pas imbriquer un composant dans un autre cycle de rendu des composants dans cette instance particulière


ok, l'extrait de code devrait fonctionner mais vous devrez configurer le nouveau fichier pour l'entrée et supprimer la logique d'état HomeScreen car elle n'est pas nécessaire et généralement un endroit où vous ne conserverez pas cet état


désolé fait quelques erreurs, list.map ((item, i) et {item} a besoin d'accolades pour la valeur sinon string


Merci beaucoup pour votre aide, la méthode pour imbriquer ou non un composant n'a pas d'importance, tant que je pouvais ajouter ou supprimer ce composant et l'utiliser valeur dans le composant parent en tant qu'état.


Je suis désolé d'avoir demandé à plusieurs reprises, comment dois-je remplacer ces pièces list.map ((item, i) et {item} ?


maintenant je saisis continuellement des textes, et comment puis-je ajouter un tout ce composant ` {list.map ((item, i) => ( {item} ))} {handleMakeNew (); }} style = {styles.buttonAdd}> Ajouter `lorsque j'appuie sur le bouton Ajouter?


merci je vais essayer de modifier ce code à ce que je veux



0
votes

Essayez ceci dans le composant enfant,

import React, { useState } from "react";
import {
  View,
  StyleSheet,
  Text,
  TouchableOpacity,
  TextInput,
} from "react-native";

export default function TestListInputItem(props) {
  const [count, setCount] = useState(1);
  const [inputValue, setInputValue] = useState('');

  function handleMakeNew() {
    setCount((v) => v + 1);
  }

  const handleInput =(text) =>{
     setInputValue(text)
      props.setInputName(text)
   }

  function RenderList() {
    return (
      <View style={styles.list}>
        <TextInput
          style={styles.InputName}
          value={inputValue}
          onChangeText={(text) => {
            handleInput(text);
          }}
        ></TextInput>
        <TouchableOpacity
          onPress={() => {
            handleMakeNew();
          }}
          style={styles.buttonAdd}
        >
          <Text>Add</Text>
        </TouchableOpacity>
      </View>
    );
  }


2 commentaires

Bien que j'aie essayé ce code, je dois toujours définir le curseur chaque fois que j'entre 1 texte ...


créer une collation expo pour que je puisse voir le code. snack.expo.io