React.js - 将更改处理函数传递给深层嵌套的表单组件

时间:2017-01-02 06:54:29

标签: forms reactjs redux react-redux

我有一个表单,我想使用 React.js 进行渲染,并允许用户编辑输入并将其提交给服务器。这是一个产品清单。每个 tr 代表一个产品ID,其数量,名称,价格,类别可由用户更改。它有下拉文字输入。

我想在以下组件中细分:

  1. 产品
  2. 产品
  3. CategoryDropdown
  4. ProductList 包含产品包含 CategoryDropdown 。现在我必须将 handleCategoryChange 函数传递给 CategoryDropDown 组件。因此 ProductList 会将此作为支持传递给产品,它会将其作为支柱传递给 CategoryDropDown

    这是正确的方法吗?如果我的表单在更深层次的嵌套组件中变得更复杂怎么办?我应该继续将处理程序函数作为属性从一直到最后一直传递吗?或者我应该考虑使用 redux

    <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 个答案:

答案 0 :(得分:2)

我的建议是使用product格式保留state组件,其中包含onCategoryChange处理程序。

你需要这样的东西。

ProductList组件:

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>
    )
  }
}

答案 1 :(得分:0)

您可以将某种onChange函数从表单传递给所有子元素&amp; subchildren。

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