如何从输入组件中获取值(学习目的)?
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 />
;
【讨论】:
你能解释一下你的逻辑和步骤吗?以上是关于如何从输入组件中获取值(学习目的)?的主要内容,如果未能解决你的问题,请参考以下文章