Как я могу получить значения из входных компонентов (для учебных целей)?

#javascript #react-native #function #jsx

#javascript #react-native #функция #jsx

Вопрос:

Моя проблема в том, что я пытаюсь обработать значение моих входных данных, которые пользователь определяет, какой ввод он хочет, с помощью вызова API.

Вот где я получаю значения :

  const handleClick = buttonTitle => async () => {
    await renderField(buttonTitle).then(response => {               
      navigation.navigate('FormScreen', {
        collectionKey: buttonTitle.slice(7),
        paramKey: JSON.stringify(response),
      });     
  });
  };
 

Render field — это вызов API, который возвращает меня {"message": [{"_id": "618e4c23db08f70b719f3655", "author": "adicionarei posteriormente", "ceatedAt": "2021-11-12 08:12:32", "field": "abc", "fieldtype": "Text"}, {"_id": "618e4c9ddb08f70b719fae37", "author": "adicionarei posteriormente", "ceatedAt": "2021-11-12 08:14:35", "field": "Animal", "fieldtype": "Text"}]}

Затем у меня есть компонент формы, где я получаю некоторые необходимые компоненты и отображаю их для пользователя:

 const FormScreen = ({route, navigation}) => {
  return (
    <Container>
      <InputBody route={route.params.paramKey} navigation={navigation} />
    </Container>
    // => handle submit Input it in here ?
  );
};
 

Для моего inputbody компонента у меня есть следующий код (помня, что ( body.map это ответ на вызов api):

   return (
    <>   
    {Object.keys(Body).length > 0 ? (     
      Body.map(item => (
        <React.Fragment key={uuid.v4()}><Texto>{item.field}</Texto>  
           {renderContent(item.fieldtype,item.field)}
        </React.Fragment>
      ))
    ) : (
      <ActivityIndicator size="large" color="#eb6b09" />
    )}
    </>
  )
}
 

Затем у меня есть мой renderContent (где я получаю тип поля как a string и имя поля, которое string также является a).

 function renderContent(type,field) {
    switch(type) {     
      case 'Numeric':
      return <NumberInput key={field} keyboardType="numeric" />
     case 'Text':
      return <TextInput key={field} />
    }
  }
 

Помните, что: каждый тип поля может отображаться более одного раза.
(Например: у меня может быть одна форма с более чем 1 вводом текста), тогда мой вопрос: как я могу обрабатывать значения моего ввода, зная, что он может иметь любой тип ввода ( Numeric or Text )?

obs: я могу показывать любую информацию.

Ответ №1:

 
    const Input = ({value,keyboardType,onChange})=>{
      return(
        <TextInput value={value} keyboardType={keyboardType} onChangeText={onChange} /> 
      )
    }


    const [payload,setPayload] = useState({});

    const onValue=(e,field)=>{
      let tempPayload = {...payload};
      tempPayload[field] = e;
      setPayload(tempPayload)
    }


    const renderComponent = (fieldObj)=>{
      switch(fieldObj.type):
        case "Text":
          return <Input keyboardType="default" onChange={(e)=>onValue(e,fieldObj.field)} value={payload[fieldObj.field]||""}/>
        case "Number":
          return <Input keyboardType="numeric" onChange={(e)=>onValue(e,fieldObj.field)} value={payload[fieldObj.field]||""} />
        case "Dropdown":
          return <Dropdown options={fieldObj.options} />  //if you want to add dropdown, radio buttons etc in future
    }

 

Идея довольно проста. Сохраните значения из полей формы в объекте payload . Имя — это имя поля, например. Животное. Значение — это значение этого поля. Вы также можете инициализировать объект, указав все ключи и их значения как пустые или значение по умолчанию, которое вы получаете из api. Итак, если поля, которые мы отобразили, — это Animal и Car. Полезная нагрузка будет

 {
  'Animal':'Tiger',
  'Car':'BMW'
}
 

Это обрабатывается с помощью функции onValue . Вы также можете добавить проверку в эту функцию.Например, если вы передаете регулярное выражение с помощью своего api для этого поля, вы можете проверить значение с помощью регулярного выражения.

Комментарии:

1. Спасибо за ваш ответ, но когда я добавляю это, моя клавиатура скрывается в случае изменения, после каждой клавиши, которую я нажимаю, моя клавиатура скрывается, вы знаете почему? @user9747

2. Обычно это происходит, когда родительский компонент входного компонента выполняет повторную отправку.

Ответ №2:

Это было немного сложно, поэтому я упростил его, я думаю, вы должны понимать логику, стоящую за этим.

 import React, { useState } from 'react';
import { TextInput } from 'react-native';

const createInitialState = (inputList) => {
  return inputList.reduce((accumulator, currentValue) => {
    return {
      ...accumulator,
      [currentValue.field]: '',
    };
  }, {});
};


const SomeScreen = () => {
  const initialDataPassed = [
    {
      '_id': '618e4c23db08f70b719f3655',
      'author': 'adicionarei posteriormente',
      'ceatedAt': '2021-11-12 08:12:32',
      'field': 'abc',
      'fieldType': 'Text',
    }, {
      '_id': '618e4c9ddb08f70b719fae37',
      'author': 'adicionarei posteriormente',
      'ceatedAt': '2021-11-12 08:14:35',
      'field': 'Animal',
      'fieldType': 'Text',
    },
    {
      '_id': '618e4c9ddb08f70b719fae37',
      'author': 'adicionarei posteriormente',
      'ceatedAt': '2021-11-12 08:14:35',
      'field': 'Animal',
      'fieldType': 'Number',
    },
  ];

  return (
    <Form inputList={initialDataPassed} />
  );
};

const Form = ({ inputList }) => {
  const [formState, setFormState] = useState(createInitialState(inputList));

  return (
    <>
      {inputList.map((item) => {
        const handleTextInputValueChange = (text) => {
          // this is solution is better if we base on old value
          setFormState(oldState => ({
            ...oldState,
            [item.field]: text
          }))
        };

        return <Input key={item.field} value={formState[item.field]} onChangeText={handleTextInputValueChange} fieldType={item.fieldType} />
      })}
    </>
  );
};


const Input = ({value, onChangeText, fieldType}) => {
  const keyboardType = fieldType === 'Number' ? 'numeric' : undefined;

  return <TextInput value={value} keyboardType={keyboardType} onChangeText={onChangeText} />
};
 

Комментарии:

1. Не могли бы вы объяснить мне свою логику и шаги?

Ответ №3:

Если вам просто нужны эти типы ввода, вы могли бы сделать это следующим образом:

Сначала определите и объект для сопоставления ваших типов полей с типами ввода html:

 const inputTypesMapper = {
  Numeric: "number",
  Text: "text",
  Boolean: "checkbox"
};
 

И, таким образом, вы можете отобразить их следующим образом:

 <div className="App">
 {data.message.map(({ fieldtype, field }) => (
   <input type={inputTypesMapper[fieldtype]} defaultValue={field} />
 ))}
</div>
 

Вот вам пример

Но если вы хотите отображать разные компоненты для каждого типа поля, вы можете сделать следующее:

Сначала определите и объект для сопоставления ваших типов полей с типами ввода html:

 const inputTypesMapper = {
  Text: ({ value }) => {
    return <input type={"text"} defaultValue={value} />;
  },
  MultipleOptions: ({ value }) => {
    return (
      <select>
        {value.map(({ id, value }) => {
          return <option value={id}>{value}</option>;
        })}
      </select>
    );
  }
};
 

И, таким образом, вы можете отобразить их следующим образом:

   return (
    <div className="App">
      {data.message.map(({ fieldtype, field }) => {
        const renderInput = inputTypesMapper[fieldtype];

        return renderInput({ value: field });
      })}
    </div>
  );
 

Вот вам пример