问题
I have a modal form with a form that uses Formik
. Here are two pictures that show two states of that form that can be toggled with a switch.Initially I fill text into fields which can be added dynamically and stored as an array with .
The second picture shows how I toggled to textarea
. There you can also add text with commas that will be turned into an array.
Is there any way to fill data in input fields from the first screen, toggle into textarea
and access already inputted data.
I understand formik keeps that state somewhere. But at the moment these fields have a separate state. Here is my component:
class ModalForm extends React.Component {
constructor(props) {
super(props);
this.state = {
disabled: true,
};
}
onChange = () => {
this.setState({
disabled: !this.state.disabled,
});
};
render() {
var {
visible = false,
onCancel,
onRequest,
submitting,
setSubscriberType,
editing,
subscriptionTypeString,
tested,
selectedGates,
} = this.props;
const { gateId } = selectedGates.length && selectedGates[0];
const handleSubmit = values => {
console.log(values);
onRequest && onRequest({ gateId, ...values });
};
const { disabled } = this.state;
return (
<Modal
footer={null}
closable
title="Список абонентов для выбранного гейта"
visible={visible}
onCancel={onCancel}
onOk={handleSubmit}
destroyOnClose
width="600px"
>
<StyledDescription>
<Switch onChange={this.onChange} />
<StyledLabel>массовый ввод</StyledLabel>
</StyledDescription>
<Formik
initialValues={{ abonents: [''] }}
onSubmit={handleSubmit}
render={({ values, handleChange }) => (
<Form>
{disabled ? (
<FieldArray
name="abonents"
render={arrayHelpers => {
return (
<div>
{values.abonents.map((value, index) => (
<div key={index}>
<MyTextInput
placeholder="Абонент ID"
name={`abonents.${index}`}
value={value}
onChange={handleChange}
/>
<Button
shape="circle"
icon="delete"
onClick={() => {
arrayHelpers.remove(index);
}}
/>
</div>
))}
<Button type="dashed" onClick={() => arrayHelpers.push('')}>
<Icon type="plus" />Добавить абонента
</Button>
</div>
);
}}
/>
) : (
<StyledField
placeholder="Введите ID абонентов через запятую"
name="message"
component="textarea"
/>
)}
<Footer>
<Button type="primary" htmlType="submit">
Запросить
</Button>
</Footer>
</Form>
)}
/>
</Modal>
);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script>
回答1:
Pretty easy, formik stores values inside values.abonents
, hence you can use it inside textarea
let { Formik, Form, Field, ErrorMessage, FieldArray } = window.Formik;
function App () {
const [disabled, setDisabled] = React.useState(false) // some boilerplate code
function submit (values) {
console.log('submit', values)
}
return (
<Formik
initialValues={{ abonents: [] }}
onSubmit={submit}
render={({ values, handleChange, setFieldValue }) => (
<Form>
<FieldArray
name='abonents'
render={arrayHelpers => {
if (!disabled) {
return (
<textarea onChange={(e) => {
e.preventDefault()
setFieldValue('abonents', e.target.value.split(', '))
}} value={values.abonents.join(', ')}></textarea>
)
}
return (
<div>
{
values.abonents.map((value, index) => (
<div key={index}>
<input
placeholder='Абонент ID'
name={`abonents.${index}`}
value={value}
onChange={handleChange}
/>
<button onClick={(e) => {
e.preventDefault()
arrayHelpers.remove(index)
}}>
-
</button>
</div>
))
}
<button onClick={(e) => {
e.preventDefault()
arrayHelpers.push('')
}}>
+
</button>
</div>
)
}}
/>
<button type='submit'>Submit</button>
<button onClick={e => {
e.preventDefault()
setDisabled(!disabled)
}}>toggle</button>
</Form>
)}
/>
)
}
ReactDOM.render(<App />, document.querySelector('#root'))
<script src="https://unpkg.com/react@16.9.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/formik/dist/formik.umd.production.js"></script>
<div id='root'></div>
回答2:
I found a solution. You have got to give the same name to the input and textarea, so whe you add text in input will automatically change text in textarea
<FieldArray
name="abonents"
render={arrayHelpers => {
and
<StyledField
placeholder="Введите ID абонентов через запятую"
name="abonents"
component="textarea"
/>
These two fields have same name so they are rendered interchangeably but have common text inside them
来源:https://stackoverflow.com/questions/58132679/how-to-access-field-data-in-other-field