2017-01-02 41 views
0

我有一个表单,我想要使用Relic.js呈现,并且还允许用户编辑输入并将其提交给服务器。这是一个产品清单。每个tr代表一个产品id,其数量,名称,价格,类别可以由用户更改。它有下拉框文本输入。React.js - 将更改处理函数传递给深度嵌套窗体组件

我想打破它在以下组件:

  1. 产品列表
  2. 产品
  3. CategoryDropdown

产品列表包含产品包含CategoryDropdown。现在我必须通过handleCategoryChange函数到CategoryDropDown组件。所以产品列表将通过这个作为一个道具产品它将通过它作为支柱类别下降

这是正确的方法吗?如果我的表单变得更复杂,甚至更深的嵌套组件?我是否应该不断地将处理函数作为一个属性从一直到最终传递?或者我应该考虑使用还原

<form> 
    <table> 
     <tr> 
      <td><input type="hidden" name="productId" value="101"/></td> 
      <td><input type="text" name="quantity"/></td> 
      <td><input type="text" name="productName"/></td> 
      <td><input type="text" name="productPrice"/></td> 
      <td> 
       <select name="productCategory"> 
        <option value="1"> Soap </option> 
        <option value="2"> Shampoo </option> 
       </select> 
      </td> 
     </tr> 
     <tr> 
      <td><input type="hidden" name="productId" value="102"/></td> 
      <td><input type="text" name="quantity"/></td> 
      <td><input type="text" name="productName"/></td> 
      <td><input type="text" name="productPrice"/></td> 
      <td> 
       <select name="productCategory"> 
        <option value="1"> Soap </option> 
        <option value="2"> Shampoo </option> 
       </select> 
      </td> 
     </tr> 
    </table> 
</form> 

回答

2

我的建议是保持product组件state的形式有onCategoryChange处理程序。

你需要这样的东西。

产品列表组件:

class ProductList extends Component{ 
    constructor(props){ 
    this.state = { 
     products: [...this.props.products]; //your actual products 
    } 
    } 

    handleEachProduct(){ 
    //takes data from each product component 
    //updates to products in state 
    } 
    handleSubmit(){ 
    //submiy entire products in state 
    } 
    render(){ 
    return(
     <table> 
     { 
      this.state.products.map(product => { 
      return(
       <Product data={product} submitProduct={this.handleEachProduct.bind(this)} /> 
      ) 
      }) 
     } 
     </table> 
    ) 
    } 
} 

产品组件。

class Product extends Component{ 
    constructor(props){ 
    this.state = { 
     quantity: value, 
     productCategory: value 
     //similarly all values 
    } 
    } 
    componentWillMount(){ 
    this.setState(this.props.data); 
    } 
    onCategoryChange(e){ 
    this.setState({productCategory:e.target.value }, function(){ 
    this.props.submitProduct(this.state); //updates state of product to ProductList 
    }); 
    //Similarly change handlers for all values in product 
    } 
    render(){ 
    retrun(
     <tr> 
      <td><input type="hidden" name="productId" value="101"/></td> 
      <td><input type="text" name="quantity"/></td> 
      <td><input type="text" name="productName"/></td> 
      <td><input type="text" name="productPrice"/></td> 
      <td> 
       <select name="productCategory" onChange={this.onCategoryChange}> 
        <option value="1"> Soap </option> 
        <option value="2"> Shampoo </option> 
       </select> 
      </td> 
     </tr> 
    ) 
    } 
} 
+0

感谢您的努力,几乎可以编码......好的方法也是如此 – dharm0us

0

您可以通过降低某种功能的onChange从形式到所有的孩子& subchildren。

或者您可以使用redux(或类似的)并将所有这些数据保存在商店中。提交表单后,您可以从商店中获取所有内容,而无需在组件树上传递任何内容。

+0

你基本上是改写我的问题:-) – dharm0us

+0

它depands您的应用程序。如果你只有这个表单,那么最好的解决方案就是使用一个redux商店。 如果你有一个更大的应用程序,并且你不想将临时表单值添加到商店,那么你可以传递onChange向下的树。这真的取决于你有什么。使用redux(或类似的东西)通常是更好的方法,但它可能是对你有什么的矫枉过正。 – Kinnza