React Native useState create loop input

Asked

Viewed 284 times

1

I have an object as follows:

var ItensMenu = [
    {title: 'Nome', type: 'input', id: 'id1'},
    {title: 'CPF', type: 'number', id: 'id2'},
    {title: 'Data de Nascimento', type: 'date', id: 'id3'},
    {title: 'Data de Cadastro', type: 'date', id: 'id4'},
]

So, I want to create a form with map(), following form:

const [date, setDate] = useState('2018-04-01 16:00:00');

            <TextInput 
               value={date}
               nativeID={nativeID}
            onChangeText={onChangeText}

How do I use useState in this case?

Because I want to build these inputs with a while, so when I make the change in the specific state, I want you to just change the referenced field. The Object will come from an API so I cannot write the useState code for each input, because the inpust that will come are of any name and quantities.


Coming back now, it worked with the help of his friend Daniel Magalhaes Now I’ll adapt to get the Rndatetimepicker

import React, { useState, useEffect }  from 'react'
import { Button, View, StyleSheet, TextInput } from 'react-native'

export default function Teste(){

    /// VIRÁ DA API - sintaxe à definir
    var ItensMenu = [
        {title: 'Nome', type: 'input', id: 'id1'},
        {title: 'CPF', type: 'number', id: 'id2'},
        {title: 'Data de Nascimento', type: 'date', id: 'id3'},
        {title: 'Data de Cadastro', type: 'date', id: 'id4'},
    ]
    /// VIRÁ DA API

    const [Itens, setItens] = useState([]);

    let ItensForm = []
    
    ItensMenu.map((item) => {
        ItensForm = [...ItensForm, item]
    })

    useEffect(() => { setItens(ItensForm) }, [])

    return(
        <View style={{flex:1, justifyContent: 'center', alignItems: 'center'}}>
            { 
            Itens.map((item, index) => {
                return(
                    <View key={'view_'+index} style={{flex:1, justifyContent: 'center', alignItems: 'center', width: '100%'}}>
                        <TextInput 
                            value={Itens[index].id} 
                            style={Css.input} 
                            onChangeText={ (value) => {
                                Itens[index].id = value
                                setItens([...Itens], Itens);                                    
                            } }
                        />
                    </View>
                )
            })
            }
            <Button title='press' onPress={ (e) => { console.log(Itens) } } />
            {/* <RNDateTimePicker
                testID="dateTimePicker"
                value={parseISO(date)}
                mode='date'
                is24Hour={true}
                display="default"
                onChange={onChange}
            /> */}
        </View>
    )
}

const Css = StyleSheet.create({
    input:{
        borderWidth: 2,
        width: '100%',
        padding: 5,
        fontSize: 20,
        marginTop: 10,
        marginBottom: 10
    }
})

This is the result of several inputs being created from an API array, and with the use of the Datetimepicker React-Native-datetimepicker, that’s what I really needed:

import React, { useState, useEffect }  from 'react'
import { Button, View, StyleSheet, TextInput } from 'react-native'
import RNDateTimePicker from '@react-native-community/datetimepicker';
import { parseISO, format  } from "date-fns";

export default function Teste(){

    /// VIRÁ DA API - sintaxe à definir
    var ItensMenu = [
        {title: 'Nome', type: 'input', id: 'id1'},
        {title: 'CPF', type: 'number', id: 'id2'},
        {title: 'Data de Nascimento', type: 'date', id: 'id3'},
        {title: 'Data de Cadastro', type: 'date', id: 'id4'},
    ]
    /// VIRÁ DA API

    const [Itens, setItens] = useState([]);
    const [showDate, setShowDate] = useState([]);
    const [date, setDate] = useState('2018-04-01 16:00:00');

    let ItensDate = []
    
    ItensMenu.map((item, idx) => {
        
        ItensDate = [...ItensDate, {showDate: false}]
        
    })

    useEffect(() => { 
        setItens(ItensMenu) 
        setShowDate(ItensDate)
    }, [])
    
    return(
        <View style={{flex:1, justifyContent: 'center', alignItems: 'center'}}>
            { 
            Itens.map((item, index) => {
                return(
                    <View key={'view_'+index} style={{flex:1, justifyContent: 'center', alignItems: 'center', width: '100%'}}>

                        {showDate[index].showDate ? 
                        <RNDateTimePicker
                            // testID="dateTimePicker"
                            value={parseISO(date)}
                            mode='date'
                            is24Hour={true}
                            display="default"
                            onChange={ (e, value) => {
                                    const formattedDate = format(
                                        value, 
                                        "'Dia' dd 'de' MMMM', às ' HH:mm'h'"
                                    );
                                    Itens[index].id = formattedDate;
                                    setItens([...Itens], Itens);
                                    showDate[index].showDate = false;
                                    setShowDate([...showDate], showDate) 
                                }
                                
                            }
                        /> 
                        :
                        null
                        }
                        <TextInput 
                            value={Itens[index].id} 
                            style={Css.input} 
                            onTouchStart={ () => {
                                    showDate[index].showDate = true;
                                    setShowDate([...showDate], showDate) 
                                } 
                            }
                            showSoftInputOnFocus={false}
                            onChangeText={ (value) => {

                                Itens[index].id = value
                                setItens([...Itens], Itens);                             
                                    
                            } }
                        />
                    </View>
                )
            })
            }
            <Button title='press' onPress={ (e) => {

                console.log(Itens)
                
            } } />            
        </View>
    )
}

const Css = StyleSheet.create({
    input:{
        borderWidth: 2,
        width: '100%',
        padding: 5,
        fontSize: 20,
        marginTop: 10,
        marginBottom: 10
    }
})

1 answer

2


In this case I would use useState to store one object with input values, and another to store the object of ItensMenu. I made an example code, I made a mix of English with Portuguese, but I think you can understand:


import React, { useState, useEffect } from "react";

export const TextInput = ({ title, type, id, value, onChange, ...props }) => {
  return (
    <div>
      <label htmlFor={id}>{title}</label>
      <input type={type} id={id} name={id} value={value} onChange={onChange} />
    </div>
  );
};

export const FormDinamico = ({ ...props }) => {
  const [itensMenu, setItensMenu] = useState([]);
  const [values, setValues] = useState({});

  //Aqui ficaria sua lógica de requisição para a API
  useEffect(() => {
    let newMenuItens = [
      { title: "Nome", type: "input", id: "id1" },
      { title: "CPF", type: "number", id: "id2" },
      { title: "Data de Nascimento", type: "date", id: "id3" },
      { title: "Data de Cadastro", type: "date", id: "id4" },
    ];
    let initialValues = {};
    newMenuItens.forEach((item) => (initialValues[item.id] = item.value || ""));
    setItensMenu(newMenuItens);
    setValues(initialValues);
  }, []);

  const handleChange = (e) => {
    let id = e.target.id;
    let value = e.target.value;
    setValues((oldValues) => ({ ...oldValues, [id]: value }));
  };

  return (
    <div>
      <form>
        {itensMenu.length &&
          itensMenu.map((item) => (
            <TextInput
              {...item}
              value={values[item.id]}
              onChange={handleChange}
              key={item.id}
            />
          ))}
      </form>
    </div>
  );
};

I haven’t had a chance to test the code above, but I believe it might give you a direction to go.

  • Your code elucidated me many things, I work with PHP and T-SQL, now q I’m getting the hang of Rect Native, there is a lot of interesting stuff for program with this language, thanks for the help!!! My goal is now to adapt to the Rndatetimepicker class.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.