简体   繁体   English

如何在ReactJS中从props.children到其父级获取数据?

[英]How to get data from props.children to its parent in ReactJS?

I'm trying to get data from a props.children [Input] to it's parent [Form], to build an all in one form component. 我正在尝试从props.children [Input]到parent [Form]的数据中获取数据,以构建一个一体的表单组件。 I am currently stuck at getting data to Input component to Form component. 我目前停留在获取数据到Input组件到Form组件上。

This is what i have done so far => 这是我到目前为止所做的=>

edit.js => 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 => 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 => 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>
        );
    }
}

For example, If post -> edit page and user -> edit page => I would like to do setting the input value inside the Form.js, Form.js will be responsible for setting the values inside those Inputs when it is mounted and it will be responsible for sending the data to the server. 例如,如果post-> edit page和user-> edit page =>我想在Form.js内设置输入值,那么在安装并安装Form.js时,Form.js将负责在这些Inputs内设置值。它将负责将数据发送到服务器。

I would like to the know, the scenario I have suggest is possible or is there a better way to do it? 我想知道,我所建议的方案是可能的,或者有更好的方法吗?

Invert control (make Input a controlled component). 反转控制(使Input为受控组件)。 Keeping state inside components unnecessarily is generally a bad design practice. 通常,不必要地在组件内部保持状态是一种不良的设计实践。 Look at the existing <input> it takes a value and an onChange . 查看现有的<input>它需要一个value和一个onChange Your component should do too. 您的组件也应该这样做。

const Input = ({
  className,
  ...rest
}) => (
  <input
    className={classNames('Input', className)}
    type="text"
    {...rest}
  />
);

Then the parent has the state for when the form is submitted in 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} />

If you want Form to listen in on state changes you could do this: 如果要让Form侦听状态更改,可以执行以下操作:

onChange = (e, originalOnChange) => {
  console.log('onChange called:', e.target.value);
  originalOnChange && originalOnChange(e);
}

// ...
const children = React.Children.map(this.props.children, child =>
  React.cloneElement(child, { onChange: e => this.onChange(e, child.props.onChange) })
);

It's a bit unorthodox but technically achievable. 这有点不合常规,但在技术上是可以实现的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM