#javascript #reactjs
#javascript #reactjs
Вопрос:
Я пытаюсь получить данные из props.children
[Input] в его parent
[Form], чтобы создать все в одном компоненте формы. В настоящее время я застрял на получении данных для ввода компонента в компонент Form.
Это то, что я сделал до сих пор =>
edit.js =>
export default class Edit extends Component {
constructor(props) {
super(props)
this.state = {
formFields: {
name: '',
email: ''
}
}
}
render() {
return (
<Form
id={ this.props.match.params.id }
onReceiveFormData={ this.onFiledDataChange.bind(this) }
>
<Input
label='name'
name='name'
value='some'
/>
<Input
label='email'
name='email'
value='email@gmail'
/>
</Form>
);
}
}
Input.js =>
export default class Input extends Component {
constructor(props) {
super(props)
this.state = {
value: this.props.value
}
}
static setValue(val) {
return val ? val : ''
}
handleInputChange = (event) => {
this.setState({
value : event.target.value
})
this.props.onInputChange({
[event.target.name] : event.target.value
})
}
render() {
return (
<input
name={ this.props.name }
value={ Input.setValue(this.state.value) }
/>
);
}
}
Form.js =>
export default class Form extends Component {
constructor(props) {
super(props)
}
saveClick() {
/**
Save logic => I want to get the field data here
**/
}
render() {
return (<div>
{
this.props.children
}
<Button
onClick={ () => this.saveClick() }
>Save</Button>
</div>
);
}
}
Например, если post -> редактировать страницу и user -> редактировать страницу =>
Я хотел бы задать входное значение внутри Form.js , Form.js будет отвечать за установку значений внутри этих входных данных при монтировании и будет отвечать за отправку данных на сервер.
Я хотел бы знать, возможен ли сценарий, который я предлагаю, или есть лучший способ сделать это?
Ответ №1:
Инвертировать элемент управления (сделать ввод контролируемым компонентом). Излишнее сохранение состояния внутри компонентов, как правило, является плохой практикой проектирования. Посмотрите на существующие <input>
, для этого требуется a value
и an onChange
. Ваш компонент тоже должен делать.
const Input = ({
className,
...rest
}) => (
<input
className={classNames('Input', className)}
type="text"
{...rest}
/>
);
Тогда родительский элемент имеет состояние на момент отправки формы в Edit.
onFormSubmit = e => {
e.preventDefault();
console.log(this.state.name, this.state.email);
}
onChange = name => e => this.setState({ [name]: e.target.value })
// ...
<Input onChange={this.onChange('name')} value={this.state.name} />
<Input onChange={this.onChange('email')} value={this.state.email} />
Если вы хотите Form
прослушивать изменения состояния, вы можете сделать это:
onChange = (e, originalOnChange) => {
console.log('onChange called:', e.target.value);
originalOnChange amp;amp; originalOnChange(e);
}
// ...
const children = React.Children.map(this.props.children, child =>
React.cloneElement(child, { onChange: e => this.onChange(e, child.props.onChange) })
);
Это немного неортодоксально, но технически достижимо.
Комментарии:
1.
this.onChange
будет метод внутри edit.js ?2. точно, добавлен пример
3. Вы также должны использовать
onSubmit
событие<form>
, а не нажатие кнопки. Ваша кнопка должна иметьtype="submit"
, но без события на ней4. Хорошо, я понял 🙂 , но то, что я пытаюсь сделать, это поместить всю повторяющуюся логику в Form.js . Я уже нашел решение с таким подходом.
5. Я понимаю это, хотя из личного опыта я предпочитаю предоставлять как можно больше контроля. В этом случае вы все равно можете выполнить этот шаблон, но сохранить состояние в
Form