反应最终形式:根据形式价值制定条件 [英] React Final Form: make conditions according to form values

查看:53
本文介绍了反应最终形式:根据形式价值制定条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要根据用户在表单的第一步中提示的值来生成一定数量的字段.

由于我正在使用向导"类< Condition/> 组件执行多步骤表单,因此无法正常工作.

基本上,我需要访问值(从功能组件内部的类中提取值),以便告诉React需要生成的页面"数.

类似这样的东西:

 导出默认值()=>{(<向导initialValues = {{}}onSubmit = {onSubmit}><向导页面><第一步/></Wizard.Page>{values.items.map((item,index)=>(< Wizard.Page key ="index">< SecondStep stepName ="item.name" key ="index"/></Wizard.Page>)}}</向导>)} 

为了根据用户创建的项目数生成N页,每个项目一页.

这种方法行不通,因为它告诉我未定义值.

这是我的向导React组件:

 从'react'导入React从'prop-types'导入PropTypes从'react-final-form'导入{Form}从'final-form-arrays'导入arrayMutators导出默认类向导扩展了React.Component {静态propTypes = {onSubmit:PropTypes.func.isRequired}静态页面=({children})=>孩子们构造函数(道具){超级(道具)this.state = {页:0,值:props.initialValues ||{}}}下一个=值=>this.setState(state =>({页面:Math.min(state.page + 1,this.props.children.length-1),价值观}))上一个=()=>this.setState(state =>({页面:Math.max(state.page-1,0)}))验证=值=>{const activePage = React.Children.toArray(this.props.children)[this.state.page]返回activePage.props.validate吗?activePage.props.validate(values):{}}handleSubmit =值=>{const {children,onSubmit} = this.propsconst {page} = this.stateconst isLastPage =页面=== React.Children.count(children)-1如果(isLastPage){返回onSubmit(值)} 别的 {this.next(values)}}使成为() {const {children} = this.propsconst {页面,值} = this.stateconst activePage = React.Children.toArray(children)[page]const isLastPage =页面=== React.Children.count(children)-1返回 (<表格initialValues = {values}validate = {this.validate}onSubmit = {this.handleSubmit}mutators = {{... arrayMutators}}>{({handleSubmit,submitting,values})=>(< form onSubmit = {handleSubmit}>{activePage}< div className =按钮居中">{page>0&&< button type ="button" onClick = {this.previous}>«上一个</button>}{!isLastPage&&< button type ="submit">下一个»</button>}{isLastPage&&< button type ="submit" Disabled = {提交}> Submit</button>}</div>< pre> {JSON.stringify(values,0,2)}</pre></form>)}</表单>)}} 

这是FirstStep组件(用户在其中插入其第一个值,它生成并排列项目.我要做的就是拉取状态值,以便根据的长度生成多个页面)第一个数组):

 导出默认值()=>(< FieldArray name ="items">{({{fields})=>(< div className ="centered-items">{fields.map((name,index)=>(< div key = {name} className ="item-row">< label htmlFor = {`商品名称-$ {index}`}}>商品:</label><字段id = {`item-name-$ {index}`}name = {`$ {name} .item`}component ="input"type ="text"placeholder =放置商品名称"/>< button type ="button" onClick = {()=>fields.remove(index)}>去掉</button></div>))}<按钮className ="centered"type ="button"onClick = {()=>fields.push({tipologia:'',numero_camere:'1'})}>新增项目</button></div>)}</FieldArray>) 

解决方案

我设法解决此问题,方法是调用 React.cloneElement()方法.此方法需要包装 activePage 变量和静态方法" Page ",这样您就可以将属性传递给子级,因此至少我设法访问了表单值在每个页面内,因此创建一些条件.

您可以在此处看到一个有效的示例:演示-Codesandbox

我仍然没有弄清楚如何在页面外部(在Wizard类内部,但在Wizard.Page方法之前)访问此值,这可能是理想的方法,因为我可以创建条件来生成/(或不生成)页面.

I need to generate a certain number of fields according to a value that the user prompts in the first step of the form.

Since I'm doing a multi-step form with a "Wizard" class <Condition /> component doesn't work.

Basically I need to access to values (pull them from the class inside the functional component) in order to tell React the number of "pages" it needs to generate.

Something like this:

export default () => {(
        <Wizard
            initialValues={{ }}
            onSubmit={onSubmit}
        >
            <Wizard.Page >
                <FirstStep />
            </Wizard.Page>

        {values.items.map((item, index) => (
            <Wizard.Page key="index">
                <SecondStep stepName="item.name" key="index" />
            </Wizard.Page>
        ) )}

        </Wizard>
)}

In order to generate N pages according to the number of items the user created, one page for each item.

This approach does not work because it tells me that the values are not defined.

This is my Wizard React Component:

import React from 'react'
import PropTypes from 'prop-types'
import { Form } from 'react-final-form'
import arrayMutators from 'final-form-arrays'

export default class Wizard extends React.Component {
   static propTypes = {
       onSubmit: PropTypes.func.isRequired
   }
   static Page = ({ children }) => children

   constructor(props) {
       super(props)
       this.state = {
           page: 0,
           values: props.initialValues || {}
       }
   }
   next = values =>
       this.setState(state => ({
           page: Math.min(state.page + 1, this.props.children.length - 1),
           values
       }))

   previous = () =>
       this.setState(state => ({
           page: Math.max(state.page - 1, 0)
       }))

   validate = values => {
       const activePage = React.Children.toArray(this.props.children)[
           this.state.page
       ]
       return activePage.props.validate ? activePage.props.validate(values) : {}
   }

   handleSubmit = values => {
       const { children, onSubmit } = this.props
       const { page } = this.state
       const isLastPage = page === React.Children.count(children) - 1
       if (isLastPage) {
           return onSubmit(values)
       } else {
           this.next(values)
       }
   }

   render() {
       const { children } = this.props
       const { page, values } = this.state
       const activePage = React.Children.toArray(children)[page]
       const isLastPage = page === React.Children.count(children) - 1
       return (
           <Form
               initialValues={values}
               validate={this.validate}
               onSubmit={this.handleSubmit}
               mutators={{...arrayMutators }}
           >
               {({ handleSubmit, submitting, values }) => (
                   <form onSubmit={handleSubmit}>

                       {activePage}

                       <div className="buttons centered">
                           {page > 0 && <button type="button" onClick={this.previous} >« Previous </button>}
                           {!isLastPage && <button type="submit">Next »</button>}
                           {isLastPage && <button type="submit" disabled={submitting}>Submit</button>}
                       </div>

                       <pre>{JSON.stringify(values, 0, 2)}</pre>
                   </form>
               )}
           </Form>
       )
   }
}

And this is the FirstStep component (where the user inserts its first values, it generates and array of items. All I need to do is pull the values of the state in order to generate a number of pages according to the length of that first array):

export default () => (

            <FieldArray name="items">
                {({ fields }) => (
                <div className="centered-items">
                    {fields.map((name, index) => (
                        <div key={name} className="item-row">
                            <label htmlFor={`item-name-${index}`}>item: </label>
                            <Field
                                id={`item-name-${index}`}
                                name={`${name}.item`} 
                                component="input"
                                type="text"
                                placeholder="Place Item Name"
                            />
                            <button type="button" onClick={() => fields.remove(index)}>
                                Remove
                            </button>
                        </div>
                    ))}
                    <button
                        className="centered"
                        type="button"
                        onClick={() => fields.push({ tipologia: '', numero_camere: '1' })}
                    >
                        Add Item
                    </button>
                </div>
                )}
            </FieldArray>
)

解决方案

I manage to solve this problem calling React.cloneElement() method. This method needs to wrap either activePage variable and the static method "Page", in this way you can pass properties to children, so at least I manage to access the form values inside every page and so create some conditions.

You can see a working example here: Demo - Codesandbox

I still haven't figured out how to access this values outside the page (inside Wizard Class but before Wizard.Page method, this could be the ideal way because I can create conditions in order to generate/(or not generate) pages.

这篇关于反应最终形式:根据形式价值制定条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆