如何在 redux 中管理这个表单?

Posted

技术标签:

【中文标题】如何在 redux 中管理这个表单?【英文标题】:How do I manage this form in redux? 【发布时间】:2018-05-19 20:18:09 【问题描述】:

我正在建立一个在线商店,我正在创建一个表单,用户将在其中选择一个选项,该选项的价格将被添加到总价中

class SingleProduct extends Component 
constructor(props) 
    super(props);
    this.state = ;

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  
  handleChange(event) 
    this.setState(value: event.target.value);
  
  
  handleSubmit(event) 
    event.preventDefault();

    var products = this.props.products.products;
      
         var ID = this.props.router.location.pathname.slice(9, 100)
      
            var productArray = this.props.products.products.data.filter(function(product) 
              return product.id === ID;
            )
            
            var product = productArray[0];
      var addToCart = (id, options) => 
        this.props.dispatch((dispatch) => 
            
            if(this.props.value == 'select')
                this.props.product.options = 0;
            
            else if(this.state.value == 'no-edge')
                this.props.product.options = 0;
            
            else if(this.state.value == '2inchHemOnly')
                this.props.product.options = 20;
            
            else if(this.state.value == '2inchHG')
                this.props.product.options = 25;
            
            else if(this.state.value == 'HandG')
                this.props.product.options = 30;
            
            else if(this.state.value == 'rope-rail')
                this.props.product.options = 35;
            
            else if(this.state.value == 'pole-pocket')
                this.props.product.options = 40;
            
        var values = this.props.product.values;
        var options = this.props.product.options;
          api.AddCart(id, this.props.product.quantity)

          .then((options) => 
              console.log(options)
              dispatch(type: "Update_Options", payload: options)
          )
          .then((values) => 
            console.log(values)
            dispatch(type: "Update_Value", payload: values)
          )
          .then((cart) => 
            console.log(cart)
            dispatch(type: "Cart_Updated", gotNew: false)
          )

          .then(() => 
              dispatch(type: "Fetch_Cart_Start", gotNew: false)

              api.GetCartItems()
                
              .then((cart, options, values) => 
                dispatch(type: "Fetch_Cart_End", payload: cart, gotNew: true)
                dispatch(type: "Update_Options", payload: options)
                dispatch(type: "Update_Value", payload: values)
              )
          )
          .then(() => 
              console.error(options)
          )
          .catch((e) => 
            console.log(e)
          )
        )
      
      
      addToCart(product.id);
  
return (
    <main role="main" id="container" className="main-container push">
    <section className="product">
      <div className="content">
          <div className="product-listing">
   
              <div className="product-description">
                  <p className="price"><span className="hide-content">Unit price </span>'$' + product.meta.display_price.with_tax.amount/100 + this.props.product.options</p>
                <form className="product" onSubmit=this.handleSubmit.bind(this)>
                    <label>SELECT EDGING OPTION</label>
                    <select name="edging" value=this.state.value onChange=this.handleChange>
                            <option value="select">-- Please select --</option>
                            <option value="no-edge">No Edge</option>
                            <option value="2inchHemOnly">2” Hem Only</option>
                            <option value="2inchHG">2” Hem and Grommets 24” On Center</option>
                            <option value="HandG">Hem and Grommets 12” on Center</option>
                    </select>
                    
                        <div className="quantity-input" style=style>
                            <p className="hide-content">Product quantity.</p>
                            
                           
                        <button type="submit" className="submit">Add to cart</button>
                </form>
              </div>
          </div>
          
      </section>
      <MailingList />
  </main>
  )



export default connect(mapStateToProps)(SingleProduct);

这是我的减速器:

const initialState = 
quantity: 1,
options: 0,
values: [
 value: '-- Please select --' ,
 value: 'No Edge' ,
 value: '2” Hem Only' ,
 value: 'No Edge' ,
 value: '2” Hem and Grommets 24” On Center' ,
 value: 'Hem and Grommets 12” on Center' 
]


const ProductReducer = (state=initialState, action) => 
switch (action.type) 
case "Update_Quantity": 
  return ...state, quantity: action.payload;

case "Update_Options": 
  return ...state, 
    options: action.payload;

case "Update_Value": 
  return ...state, 
    value: action.payload;

default: 
  return ...state;


;

export default ProductReducer;

当我添加到购物车时,我的“价值”是未定义的。刷新时,“选项”回到 0。我的数量保持在状态。我只是不知道为什么会这样。

【问题讨论】:

【参考方案1】:

react 文档声明:无论您将组件声明为函数还是类,它都不能修改自己的 props。

因此,您可能希望将道具复制到变量中,然后修改该副本。一种方法可能是放置这一行:

let propsCopy =  ...this.props 

在线上方var addToCart = (id, options) =&gt;

然后在后续行中使用 propsCopy 代替 props。

【讨论】:

这不起作用。 props 在 var addToCart = (id, options) => 行上方未定义 我的错误。它应该是在您第一次使用 this.props 之前的let propsCopy = ...this.props 。我已经编辑了答案。 澄清一下:在声明为类的组件中,道具必须评估为 this.props。 (在函数式样式组件中,道具作为参数传入,因此可以直接作为道具进行评估)。

以上是关于如何在 redux 中管理这个表单?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 redux-form 绑定连接到表单的输入

如何将 Django-Registration-Redux 注册表单放在其他页面上?

如何在 React/Redux 中本地管理组件的状态

ReactJS表单应用程序:如何阻止父组件重新渲染? /使用redux共享状态的正确方法

如何使用 redux 模式在 react native 中刷新组件?

如何将redux与antd表单验证集成