Reactjs redux表单以二进制方式将对象注入FieldArray`field`属性

Reactjs redux表单以二进制方式将对象注入FieldArray`field`属性,reactjs,redux,redux-form,Reactjs,Redux,Redux Form,我试图实现的是一个类似于中的动态FieldArray,但不同的是,我添加到列表中的每个对象都已具有所有属性(我必须显示),但我需要从其他两个属性中计算一个 看看这个例子: import React from 'react' import { compose } from 'redux'; import { connect } from 'react-redux'; import { Field, FieldArray, reduxForm, formValueSelector } from 'r

我试图实现的是一个类似于中的动态FieldArray,但不同的是,我添加到列表中的每个对象都已具有所有属性(我必须显示),但我需要从其他两个属性中计算一个

看看这个例子:

import React from 'react'
import { compose } from 'redux';
import { connect } from 'react-redux';
import { Field, FieldArray, reduxForm, formValueSelector } from 'redux-form'

const renderField = ({ input, label, type, meta: { touched, error } }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} type={type} placeholder={label}/>
      {touched && error && <span>{error}</span>}
    </div>
  </div>
)

const renderSelect = (products) => (
  <div>
    <label>Select Product to Add</label>
    <div>
      <Field name="products" component="select">
        <option></option>
        {products.map(p => <option value={p.id}>{p.name}</option>)}
      </Field>
    </div>
  </div>
);

const renderCompetences = ({ fields, meta: { touched, error, submitFailed }}) => {
  return (
    <div>
      {/* <div>
        <button type="button" onClick={() => fields.push({})}>Add Competence</button>
        {(touched || submitFailed) && error && <span>{error}</span>}
      </div> */}
      <ul>
        {fields.map((competence, index) =>
                    <li key={index}>
                      <h4>Competence #{index + 1}</h4>
                      <Field
                        name={`${competence}.singlePrice`}
                        type="number"
                        component={renderField}
                        label="Single Price"/>
                      <Field
                        name={`${competence}.standardQuantity`}
                        type="number"
                        component={renderField}
                        label="Standard Quantity"/>
                      <Field
                        name={`${competence}.totalPrice`}
                        type="number"
                        component={renderField}
                        label="Total Price"/>

                      <button 
                        type="button" 
                        onClick={() => fields.remove(index)} 
                        style={{color: 'red'}}
                        >
                        ✘
                      </button>
                    </li>
                   )}
      </ul>
    </div>
  );
}

const FieldArraysForm = (props) => {
  const { handleSubmit, pristine, reset, submitting, products, productsValue } = props;

  return (
    <form onSubmit={handleSubmit}>
      <Field name="recipientName" type="text" component={renderField} label="Recipient Name"/>
      <FieldArray name="competences" component={renderCompetences} />
      {renderSelect(products)}
      <div>
        <button type="submit" disabled={submitting}>Submit</button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
      </div>
    </form>
  )
}

const selector = formValueSelector('fieldArrays');

const mapStateToProps = (state) => {
  const productsValue = selector(state, 'products');
  return { productsValue };
};

export default compose(
  connect(mapStateToProps),
  reduxForm({
    form: 'fieldArrays'
  })
)(FieldArraysForm);
下面是一个测试某些解决方案的工作示例:


非常感谢你能给予的任何帮助

这就是我提出的解决方案:

import React from 'react'
import { compose } from 'redux';
import { connect } from 'react-redux';
import { Field, FieldArray, reduxForm, formValueSelector } from 'redux-form'

const renderField = ({ input, label, type, meta: { touched, error } }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} type={type} placeholder={label}/>
      {touched && error && <span>{error}</span>}
    </div>
  </div>
)

const renderCalcField = ({ input, label, type, meta: { touched, error }, calc }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} type={type} placeholder={label} value={calc()} />
      {touched && error && <span>{error}</span>}
    </div>
  </div>
)

const renderCompetences = ({ fields, meta: { touched, error, submitFailed }, products, productSelectValue }) => {
  return (
    <div>
      <ul>
        {fields.map((competence, index) =>
                    <li key={index}>
                      <h4>Competence #{index + 1}</h4>
                      <Field
                        name={`${competence}.singlePrice`}
                        type="number"
                        component={renderField}
                        label="Single Price"
                        onChange={() => {
                          const current = fields.get(index);
                          current.totalPrice = current.singlePrice * current.standardQuantity;
                          fields.remove(index);
                          fields.insert(index, current);
                        }}
                        />
                      <Field
                        name={`${competence}.standardQuantity`}
                        type="number"
                        component={renderField}
                        label="Standard Quantity"
                        />
                      <Field
                        name={`${competence}.totalPrice`}
                        type="number"
                        component={renderCalcField}
                        props={{calc: () => {
                          const current = fields.get(index);
                          return current.singlePrice * current.standardQuantity;
                        }}}
                        label="Total Price"
                        />

                      <button 
                        type="button" 
                        onClick={() => fields.remove(index)} 
                        style={{color: 'red'}}
                        >
                        ✘
                      </button>
                    </li>
                   )}
      </ul>
      <div>
        <Field name="productSelect" component="select">
          <option>Select product</option>
          {products.map(p => <option value={p.id}>{p.name}</option>)}
        </Field>
        <button type="button" onClick={() => {
            const selectedProduct = products.find(p => p.id === productSelectValue);
            fields.push(selectedProduct);
          }}>Add</button>
        {(touched || submitFailed) && error && <span>{error}</span>}
      </div>
    </div>
  );
}

const FieldArraysForm = (props) => {
  const { handleSubmit, pristine, reset, submitting, products, productSelectValue } = props;

  return (
    <form onSubmit={handleSubmit}>
      <Field name="recipientName" type="text" component={renderField} label="Recipient Name"/>
      <FieldArray name="competences" component={renderCompetences} props={{products, productSelectValue}}/>
      <div>
        <button type="submit" disabled={submitting}>Submit</button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
      </div>
    </form>
  )
}

const selector = formValueSelector('fieldArrays');

const mapStateToProps = (state) => {
  const productSelectValue = selector(state, 'productSelect');
  return { productSelectValue };
};

export default compose(
  connect(mapStateToProps),
  reduxForm({
    form: 'fieldArrays'
  })
)(FieldArraysForm);
从“React”导入React
从'redux'导入{compose};
从'react redux'导入{connect};
从'redux form'导入{Field,FieldArray,reduxForm,formValueSelector}
常量renderField=({input,label,type,meta:{toucted,error}})=>(
{label}
{触摸&&error&&{error}
)
const rendercalfield=({input,label,type,meta:{toucted,error},calc})=>(
{label}
{触摸&&error&&{error}
)
const renderCompetences=({fields,meta:{toucted,error,submitFailed},products,productSelectValue})=>{
返回(
    {fields.map((能力,索引)=>
  • 能力#{index+1} { const current=fields.get(索引); current.totalPrice=current.singlePrice*current.standardQuantity; 字段。删除(索引); 字段。插入(索引,当前); }} /> { const current=fields.get(索引); 返回current.singlePrice*current.standardQuantity; }}} label=“总价” /> 字段。删除(索引)} 样式={{color:'red'}} > ✘
  • )}
精选产品 {products.map(p=>{p.name}} { const selectedProduct=products.find(p=>p.id==productSelectValue); 字段。推送(所选产品); }}>加 {(触摸| |提交失败)&&error&&error} ); } const FieldArraysForm=(道具)=>{ const{handleSubmit,pristine,reset,submiting,products,productSelectValue}=props; 返回( 提交 明确的价值观 ) } 常量选择器=formValueSelector('fieldArrays'); 常量mapStateToProps=(状态)=>{ const productSelectValue=选择器(状态为“productSelect”); 返回{productSelectValue}; }; 导出默认组合( 连接(MapStateTops), 红肿({ 表格:'FieldArray' }) )(现场表格);

(有时它会出现加载问题,但这并不取决于我的示例)

为什么不在任何地方使用
productsValue
?我不明白那个值是用来做什么的。我提出它是因为我认为它可能有用,但经过几次尝试。。。我不知道是不是这样useful@ErikR. 有什么消息吗?我的问题清楚了吗?任何帮助都将不胜感激。再次感谢Webpackbin不适合我-(它运行,但不允许我选择其他文件或编辑现有文件。
import React from 'react'
import { compose } from 'redux';
import { connect } from 'react-redux';
import { Field, FieldArray, reduxForm, formValueSelector } from 'redux-form'

const renderField = ({ input, label, type, meta: { touched, error } }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} type={type} placeholder={label}/>
      {touched && error && <span>{error}</span>}
    </div>
  </div>
)

const renderCalcField = ({ input, label, type, meta: { touched, error }, calc }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} type={type} placeholder={label} value={calc()} />
      {touched && error && <span>{error}</span>}
    </div>
  </div>
)

const renderCompetences = ({ fields, meta: { touched, error, submitFailed }, products, productSelectValue }) => {
  return (
    <div>
      <ul>
        {fields.map((competence, index) =>
                    <li key={index}>
                      <h4>Competence #{index + 1}</h4>
                      <Field
                        name={`${competence}.singlePrice`}
                        type="number"
                        component={renderField}
                        label="Single Price"
                        onChange={() => {
                          const current = fields.get(index);
                          current.totalPrice = current.singlePrice * current.standardQuantity;
                          fields.remove(index);
                          fields.insert(index, current);
                        }}
                        />
                      <Field
                        name={`${competence}.standardQuantity`}
                        type="number"
                        component={renderField}
                        label="Standard Quantity"
                        />
                      <Field
                        name={`${competence}.totalPrice`}
                        type="number"
                        component={renderCalcField}
                        props={{calc: () => {
                          const current = fields.get(index);
                          return current.singlePrice * current.standardQuantity;
                        }}}
                        label="Total Price"
                        />

                      <button 
                        type="button" 
                        onClick={() => fields.remove(index)} 
                        style={{color: 'red'}}
                        >
                        ✘
                      </button>
                    </li>
                   )}
      </ul>
      <div>
        <Field name="productSelect" component="select">
          <option>Select product</option>
          {products.map(p => <option value={p.id}>{p.name}</option>)}
        </Field>
        <button type="button" onClick={() => {
            const selectedProduct = products.find(p => p.id === productSelectValue);
            fields.push(selectedProduct);
          }}>Add</button>
        {(touched || submitFailed) && error && <span>{error}</span>}
      </div>
    </div>
  );
}

const FieldArraysForm = (props) => {
  const { handleSubmit, pristine, reset, submitting, products, productSelectValue } = props;

  return (
    <form onSubmit={handleSubmit}>
      <Field name="recipientName" type="text" component={renderField} label="Recipient Name"/>
      <FieldArray name="competences" component={renderCompetences} props={{products, productSelectValue}}/>
      <div>
        <button type="submit" disabled={submitting}>Submit</button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
      </div>
    </form>
  )
}

const selector = formValueSelector('fieldArrays');

const mapStateToProps = (state) => {
  const productSelectValue = selector(state, 'productSelect');
  return { productSelectValue };
};

export default compose(
  connect(mapStateToProps),
  reduxForm({
    form: 'fieldArrays'
  })
)(FieldArraysForm);