如何从输入组件中获取值(学习目的)?

Posted

技术标签:

【中文标题】如何从输入组件中获取值(学习目的)?【英文标题】:How can I get values from input components (study purposes)? 【发布时间】:2022-01-12 13:30:53 【问题描述】:

我的问题是我试图通过 API 调用处理我的输入值,用户定义了他想要的输入。

这是我获取值的地方:

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

渲染字段是一个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" />
    )
    </>
  )

然后我有我的渲染内容(我得到字段的类型为string 和字段的名称为string)。

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】:

如果你只想要this input types,你可以这样:

首先,定义将字段类型映射到 html 输入类型的对象:

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

因此您可以将它们呈现如下:

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

Here you go an example

但是如果你想为每个字段类型渲染不同的组件,你可以这样做:

首先,定义将字段类型映射到 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>
  );

Here you go an example

【讨论】:

【参考方案2】:

    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 为该字段传递正则表达式,则可以使用正则表达式验证值。

【讨论】:

谢谢你的回答,但是当我把这个我的键盘隐藏在改变的情况下,在我按下键盘的每个键后隐藏,你知道为什么吗? @user9747 通常在Input组件的父组件重新渲染时发生。【参考方案3】:

这有点hacky所以我简化了它,我认为你应该了解它背后的逻辑。

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 />
;

【讨论】:

你能解释一下你的逻辑和步骤吗?

以上是关于如何从输入组件中获取值(学习目的)?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 React Hooks 在另一个组件中获取表单的输入值

Jquery - 如何从标签中获取输入值

从Vue中的子组件获取输入值

如何将两个孩子喂给 React 组件并使用值?

如何获得信用卡组件的 reactstrap 下拉值?

在 React Native Input/TextInput 中输入值时如何更新 JSON 对象值