从反应原生中使用map函数呈现的组件的父级调用子方法

时间:2017-07-11 22:36:18

标签: javascript react-native redux react-redux

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

到目前为止我尝试了什么

  1. 当我将小部件推入数组时使用refs 抛出与在渲染函数外部分配引用相关的错误
    1. 在引用的视图中包含对map的调用,并通过this.refs["myWrapper].props.children作为该视图的子项访问小部件 这种方法让我可以访问我的小部件,但是返回的对象并不包含我的方法,因此调用它们会导致错误而不是函数
  2. 代码示例

    `export class myForm extends Component {

    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>)
    }
    

    }

    `

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

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