#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>
);