繁体   English   中英

从使用本机Map函数渲染的组件的父对象调用子方法

[英]call child methods from parent of a component rendered using a map function in react native

我正在构建一个根据字段的json定义插入字段的表单,将json对象解析并传递到switch语句,该语句选择适当的小部件并将其插入数组中,此数组经过排序,然后使用数组映射呈现要实现的目标是在按下提交按钮后调用每个字段的验证字段,现在我该如何访问此元素并调用适当的验证逻辑

到目前为止我尝试过的

  1. 当我将小部件推入数组时使用ref引发与在render函数外分配ref有关的错误
    1. 将调用包装到引用视图中,并通过this.refs["myWrapper].props.children作为该视图的子级访问小部件,这种方法使我可以访问小部件,但返回的对象不包含我的方法,因此调用他们抛出错误不是功能

代码样本

`导出类myForm扩展了组件{

constructor(props){
    super(props);
    this.fields=[];
}

getFields(fields){

 let {formName,title}=this.props;

    let field,_fields=[],item;

    fields= this.sortFieldsOrder(fields);


    fields.forEach((sect,i)=>{
        for(field in sect)
        {
            item=sect[field];
            switch (item.widget){

                case "inlineText":
                    _fields.push(
                        <EbTextInput  key={field}

                                     {...{...item.props,formName,title}}
                                     field={field}
                                     label={item.hasOwnProperty("label")?item.label:""}
                                     validator={item.hasOwnProperty("validator")?item.validator:()=>{}}
                        />
                    );

                    break;
                case "hidden":

                    _fields.push(
                        <EbHiddenInput  key={field}
                                       {...{...item.props,formName,title}}
                                       field={field}
                                       label={item.hasOwnProperty("label")?item.label:""}
                                       validator={item.hasOwnProperty("validator")?item.validator:()=>{}}
                        />
                    );
                    break;
                case"modal":
                    _fields.push(

                        <EbModalInput
                                      key={field}
                                      {...{...item.props,formName,title}}
                                      field={field}
                                      fields={item.props.fields instanceof Array?this.getFields(item.props.fields):[]}
                                      label={item.hasOwnProperty("label")?item.label:""}
                                      validator={item.hasOwnProperty("validator")?item.validator:()=>{}}
                        />

                    );
                    break;
                case"filePicker":

                  let  picker=<EbFilePickerInput key={field}
                                                 {...{...item.props,formName,title}}
                                                 field={field}
                                                 label={item.hasOwnProperty("label")?item.label:""}
                                                 validator={item.hasOwnProperty("validator")?item.validator:()=>{}}
                  />;
                    picker=[picker];

                    _fields.push(
                        <EbModalInput  key={field}
                                      {...{...item.props,formName,title}}
                                      field={field}
                                      fields={picker}
                                      label={item.hasOwnProperty("label")?item.label:""}
                                      validator={item.hasOwnProperty("validator")?item.validator:()=>{}}
                        />
                    );
                    break;
                case "option":
                    _fields.push(
                        <EbOptionInput

                            key={field}
                            {...{...item.props,formName,title}}
                            field={field}
                            fields={item.props.fields instanceof Array?this.getFields(item.props.fields):[]}
                            label={item.hasOwnProperty("label")?item.label:""}
                            validator={item.hasOwnProperty("validator")?item.validator:()=>{}}                            />
                    );
                    break;
                default:

            }


        }
    });
    return _fields;
}
sortFieldsOrder(arr){
    return  arr.sort((a,b)=>{
        let keyA=Object.keys(a)[0];
        let keyB=Object.keys(b)[0];
        if(a[keyA]["order"]<b[keyB]["order"])return 1;
        if(a[keyA]["order"]>b[keyB]["order"])return -1;
        return 0;
    });
}
componentWillMount(){

    let {fields}=this.props;
    this.fields=this.getFields(fields)

}
renderFields(){
   return this.fields.map((item)=>{
        return item;
    })
}
validateForm(){
    let field;
    let fields=this.refs["wrapper"].props.children;
    let status=true;
    React.Children.map(this.refs["wrapper"].props.children, (child) => {
        if(!child.validate()){
            status= false;
            console.log("valid form cheki");
            // break;
        }
    })



   return status;
}
render(){
    return(
        <View ref="wrapper" style={[styles.flex1]}>
            {this.renderFields()}
            <Button text="Submit" onPress={(e)=>{
                if(this.validateForm()){
                    //alert("valid form")
                }
                else
                    alert("invalid form")
            }}> </Button>
        </View>)
}

}

`

在反应中,无论出于何种原因,它都是蚂蚁模式直接访问节点,所以我决定使用redux遵循上面的第一个注释,我可以发送一个验证信号,并让每个小部件验证其自己的状态,这减少了耦合,易于实现和调试所以我建议每个有相同问题的人都遵循此通行证

实际上,您可以在自己的情况下使用refs,但是与其通过在componentWillMount调用getFields来生成子组件,还不如直接在render方法中调用它。 换句话说,不需要this.fields ,您可以直接渲染它们。 只要您拥有正确的密钥,React就会正确管理缓存。

暂无
暂无

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

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