Как получить данные от props.children к его родительскому в ReactJS?

#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