Почему я не могу постоянно вводить текст при использовании компонента TexInput с реквизитом - PullRequest
1 голос
/ 05 августа 2020

Я пытаюсь создать компонент TextInput как дочерний с функцией из родительского компонента.

но тогда я не могу вводить текст как обычно (мне нужно устанавливать курсор каждый раз после Я ввожу 1 текст)

не могли бы вы сказать мне, как решить эту проблему?

заранее спасибо.

родительский компонент

import React, { useState, useEffect } from "react";
import { View, StyleSheet } from "react-native";
import TestListInputItem from "../components/TestListInputItem";

export default function HomeScreen() {
  const [name, setName] = useState("");

  const setInputName = (text) => {
    setName(text);
  };

  return (
    <View style={styles.container}>
      <TestListInputItem name={name} setInputName={setInputName} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
  },
});

дочерний компонент

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",
  },
});

Узел: 12.18.3

React-Native: 4.10.1

Expo: 3.22.3

Ответы [ 3 ]

2 голосов
/ 05 августа 2020

Как я прокомментировал, проблема в том, что ваша функция создает новый массив при каждом рендере, сбрасывающем ваше состояние, вот быстрое изменение, которое должно направить вас в правильном направлении

  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>
  )
}
0 голосов
/ 05 августа 2020

Попробуйте это в дочернем компоненте,

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>
    );
  }
0 голосов
/ 05 августа 2020

Это называется прыжком курсора. Чтобы этого избежать, в компоненте Input поддерживайте локальное состояние и используйте это значение состояния в качестве входного значения. при запуске onChange сначала обновите значение локального состояния, а затем отправьте его родительскому компоненту

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...