Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从使用react native中的map函数渲染的组件的父级调用子方法_Javascript_React Native_Redux_React Redux - Fatal编程技术网

Javascript 从使用react native中的map函数渲染的组件的父级调用子方法

Javascript 从使用react native中的map函数渲染的组件的父级调用子方法,javascript,react-native,redux,react-redux,Javascript,React Native,Redux,React Redux,我正在构建一个表单,该表单根据字段的json定义插入字段。json对象被解析并传递到一个switch语句,该语句选择一个合适的小部件并将其插入数组。该数组被排序,然后使用数组映射呈现 我需要实现的是在按下submit后调用每个字段的validate字段现在如何访问这些元素调用适当的validate逻辑 到目前为止我所尝试的 将小部件推入数组时使用refs 与在渲染函数外部指定参照相关的抛出错误 将对map的调用包装在引用的视图中,并通过this.refs[“myWrapper].props.ch

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

到目前为止我所尝试的

  • 将小部件推入数组时使用refs 与在渲染函数外部指定参照相关的抛出错误
  • 将对map的调用包装在引用的视图中,并通过
    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>)
    }
    
    构造函数(道具){
    超级(道具);
    this.fields=[];
    }
    getFields(字段){
    设{formName,title}=this.props;
    let字段,_字段=[],项;
    字段=此.sortFieldsOrder(字段);
    fields.forEach((sect,i)=>{
    用于(节中的字段)
    {
    项目=节[字段];
    开关(item.widget){
    案例“inlineText”:
    _推(
    {}}
    />
    );
    打破
    案例“隐藏”:
    _推(
    {}}
    />
    );
    打破
    “情态”一案:
    _推(
    {}}
    />
    );
    打破
    案例“文件选择器”:
    让选取器={}
    />;
    选择器=[picker];
    _推(
    {}}
    />
    );
    打破
    案例“选项”:
    _推(
    {}}                            />
    );
    打破
    违约:
    }
    }
    });
    返回_字段;
    }
    sortFieldsOrder(arr){
    返回arr.sort((a,b)=>{
    设keyA=Object.keys(a)[0];
    设keyB=Object.keys(b)[0];
    如果(a[keyA][“订单”]b[keyB][“订单”])返回-1;
    返回0;
    });
    }
    组件willmount(){
    设{fields}=this.props;
    this.fields=this.getFields(字段)
    }
    renderFields(){
    返回此.fields.map((项)=>{
    退货项目;
    })
    }
    validateForm(){
    让场;
    让fields=this.refs[“wrapper”].props.children;
    让status=true;
    React.Children.map(this.refs[“wrapper”].props.Children,(child)=>{
    如果(!child.validate()){
    状态=假;
    console.log(“有效形式cheki”);
    //中断;
    }
    })
    返回状态;
    }
    render(){
    返回(
    {this.renderFields()}
    {
    if(this.validateForm()){
    //警报(“有效形式”)
    }
    其他的
    警报(“无效表单”)
    }}> 
    )
    }
    
    }


    `

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

    实际上,您可以在您的案例中使用refs,但与其通过调用
    componentWillMount
    中的
    getFields
    来生成子组件,不如直接在
    render
    方法中调用它。换句话说,不需要使用
    this.fields
    ,您可以直接渲染它们。只要您有correct键,React将正确管理缓存。

    父对象不调用子方法。父对象传递其子对象的道具。如果父对象希望在组件层次结构中发出更改信号,则传递其子对象(ren)一组新的道具。因此,您建议我传递一些道具,可能使用redux触发验证逻辑。这将很简单,也更合法。感谢您的评论,我只想让问题停留更长时间,看看是否有不同的视图。我希望避免在每个渲染上重复字段,这就是为什么会出现组件中的.fieldsWillMountIterating on fields实际上比渲染便宜,尽管您缓存了组件,但如果重新渲染,无论您是否重新迭代字段,成本都不会有很大不同,除非您有大量字段,例如超过1000个。其次,由于您的组件看起来是无状态的,因此不会太频繁地重新渲染,而不是迭代不会经常发生。简言之,我建议将所有组件生成部分放入渲染流中,而不是缓存组件。某些机制,例如ref绑定,依赖于此。是的,在几个字段上迭代很便宜,但需要迭代三次,第一次排序,第二次获取表单上的第三个字段验证和在模态小部件中,它遵循相同的模式,因此它将有自己的子小部件,需要排序和获取字段,这使我决定在装载前执行所有这些操作,以防我流氓并放入数百个字段。如果需要,您仍然可以缓存排序结果,我的意思是不要缓存组件,cac他改为使用数据结构。