如何在 ReactJS 中将更改的状态从子组件传递给其父组件

Posted

技术标签:

【中文标题】如何在 ReactJS 中将更改的状态从子组件传递给其父组件【英文标题】:How to pass the changed state from child component to its parent in ReactJS 【发布时间】:2019-02-11 04:38:02 【问题描述】:

我想了解如何在ReactJS 中将更改的状态从子组件传递到其父组件?到目前为止,以下代码更改了子状态,但没有更改父状态,有什么线索我做错了吗?

我正在使用reduxmongodb 获取产品数组。

产品数组示例:

[
    
        “_id”: “2331”, 
        “department”: “Shoes”,
        “category”: “Shoes/Women/Pumps”,
        “name”: “Calvin Klein”,
        “title”: “Evening Platform Pumps”,
        “description”: “Perfect for a casual night out or a formal event.”,
        “style”: “Designer”,
        "colors": ["red","yellow","red","black"]
    ,

    
      “_id”: “30671”, 
      “department”: “Shoes”,
      “category”: “Shoes/Women/Pumps”,
      “name”: “zara”,
      “title”: “Evening Platform Pumps”,
      “description”: “Perfect for a casual night out or a formal event.”,
      “style”: “Designer”,
      "colors": ["red","yellow","red","black"]
    
]

父组件

  import React,  Component  from 'react'

  class Parent extends Component 
    constructor(props) 
      super(props);

      this.state = 
        products: [],
      ;
    

    componentDidMount() 
      this.props.getProducts();
    

    componentDidUpdate(prevProps, prevState) 
      if (this.props.product.products !== prevState.products) 
        this.setState( products: this.props.product.products );
      
    

    onUpdateProducts = (e) => 
      const newProducts = this.state.products;
      this.props.updateProductName(newProducts);
    ;


    render() 
      const  products  = this.state;

      if (isEmpty(products)) 
        productContent = (
          <div>
            <p className="lead text-muted">Error Empty Products </p>
          </div>
        );
       else 
        const productArr = products.map((product) => (
          <Child key=product._id product=product />
        ));

        productContent = (
          <div>
            productArr
          </div>
        );
      

      return (
        <div className="container">
          productContent
          <div className="row">
              <div className="col-md-12">
                <button className="btn " onClick=this.onUpdateProducts>
                  Submit
                </button>
              </div>
            </div>
        </div>
      )
    
  

  const mapStateToProps = (state) => (
    product: state.product
  );

  export default connect(mapStateToProps, 
    getProducts,updateProductName
  )(Parent);

子组件

  import React,  Component  from 'react'

  export default class Child extends Component 
    constructor(props) 
      super(props);
      this.state = 
        product: this.props.product,
      ;
    

    componentDidUpdate(prevProps, prevState) 
      if (this.props.product !== prevProps.product) 
        this.setState(
          product: this.props.product
        );
      
    

    onChangeProductName = (e) => 
      const newProduct = Object.assign(, this.state.product, 
        name: e.target.value
      );

      this.setState( product: newProduct , function() 
        console.log('onChangeProductName: ', this.state.product);
      );
    ;

    render() 
      const  product  = this.state;
      return (
        <div>
          <TextInput
              placeholder="Product Name"
              name="prd_name"
              value=product.name
              onChange=this.onChangeProductName
            />
        </div>
      )
    
  

【问题讨论】:

我认为你做错了,解决方案是从这些组件中删除状态,并通过 redux 处理产品名称更改 => 每次用户修改输入时调度一个动作,它可以使用像 redux-form 这样的库更容易实现 【参考方案1】:

你必须给孩子一个函数。

在子组件中,您将 state 设置为等于 props 值,然后您正在更新 state。这与父类无关 - 您也不应该修改 props 。

解决方案是将函数从父级传递给子级。这个函数会更新父状态,因为你将父状态传递给子状态,它也会被更新。

因此,在您的父类中,您可以执行以下操作:

onChangeProductName = (value, i) => 
  const new_product_array = [...this.state.products];
  new_product_array[i].name = value;

  this.setState( products: new_product_array);
;

您需要将此传递给孩子

const productArr = products.map((product, i) => (
   <Child
      key=product._id
      product=product onChangeName=this.onChangeProductName.bind(this)
      index=i />
));

然后在孩子中调用它

<TextInput
  placeholder="Product Name"
  name="prd_name"
  value=product.name
  onChange=() => this.props.onChangeName(product, this.props.index)
/>

子组件就不需要所有的状态跟踪了。

【讨论】:

【参考方案2】:

一个简单的示例将解释将更改的状态从子级传递给父级的概念。

组件 A:

export default class A extends Component

  //This is a callback
  handleStateChange = (value) =
    console.log("value", value);//you get the value here when state changes in B(Child) component
  
  render()
    return(
      <div>
        <B handleStateChange=this.handleStateChange />
      </div>
    )
  

组件 B:

export Class B extends Component
  constructor(props)
    super(props);
    this.state=
       value: "01"
    
  

  handleButton = () => 
     const value = "02";
     this.setState(
       value: "02"
     );
     this.props.handleStateChange(value);
  
  render()
    return(
      <div>
        <button onClick=this.handleButton />
      </div>
    )
  

或者调用 this.props.handleStateChange(this.state.value); 也可以直接传递状态如果您想传递更新的状态,则 this 在任何事件处理程序上直接呈现

正如@Ying zuo 所说,您需要使用redux 来获取父组件中子组件的更改状态值。

当子组件中的状态发生变化时,您通过将值作为参数传递来进行 redux 操作调用,并将其设置为 reducer 中的状态并获取父组件中的状态

希望能解释这个概念。

【讨论】:

【参考方案3】:

子组件更新父组件有两种方式:

    不使用Redux,可以传递一个函数作为子组件的prop,子组件可以调用这个函数来更新父组件。

    将数据存储在 Redux 存储中。子组件调度一个更新 Redux 状态的操作,父组件在其中获取数据。

【讨论】:

以上是关于如何在 ReactJS 中将更改的状态从子组件传递给其父组件的主要内容,如果未能解决你的问题,请参考以下文章

如何在反应中将最新状态从子组件传递给父组件

在 React Native 中将状态从子组件传递到父组件

ReactJS 从子组件修改父状态

React - 在下拉选择中将状态从子级传递给父级

从子组件更新父状态在 reactjs 中不起作用

如何在Angular 4中将值从子组件传递到父组件