【问题标题】:React Component: updating components, based on another component with no relationReact Component:更新组件,基于另一个没有关系的组件
【发布时间】:2019-09-03 15:21:53
【问题描述】:

不知道标题是否清楚, 这是我目前面临的问题。我的经验很少。的反应,非常感谢帮助

我有一个基于类别的产品列表,类别已定义,A、B 和 C

我为所有类别创建了单独的组件,因此 Acomponent 列出 A 下的所有产品。Bcomponent 列出 B 下的所有产品,依此类推。将它们分开是因为它们具有不同的功能。它们都显示在一个页面上,并由单个父组件调用

render(){
<div>
    <Acomponent />
    <Bcomponent />
    <Ccomponent />
</div>
}

我在列表中所有产品的前面都有一个选择框,用户可以从中更新产品的类别。因此,B 中的产品将具有带有选项 A 和 C 的选择框。

问题是我可以更新当前产品的组件,当产品类别更新时,将其从当前类别组件列表中删除,但我需要更新它被移动到的组件。

我怎样才能做到这一点?

【问题讨论】:

  • 需要更详细的示例来帮助您,您可以尝试在codesandbox.comjsfiddle.net 上进行设置吗?
  • 考虑使用上下文 API 或状态管理包,如 mobx 或 redux。
  • Redux 和全局状态管理是你唯一的选择,除非你向上传播信息,直到你找到一个共享的父节点并设置 props (但请不要这样做)。
  • @Andrew 你能解释一下 redux 吗?
  • @Emil 你能解释一下 redux 吗?

标签: reactjs components


【解决方案1】:

使用三种产品类型的父组件。用伪代码编写更改父组件中产品的方法,

class ParentComponent extends React.Component {
  constructor() {
    super()
    this.state = {
      aProducts: { ... },
      ...
    }
  }

  changeProductType = (product, oldType, newType) => {
    product.type = newType
    this.setState({ 
      [`${oldType}products`]: this.state[`${oldType}products`].filter( p => p !== product.id),
      [`${newType}products`]: [...this.state[`${newType}products`], product
    })

  }

  render() {
    return(
      <Aproducts changeProductType={this.changeProductType} products={this.state.aProducts}/>
      <Bproducts ... />
      <Cproducts ... />
    )
  }
}

您将changeProductType 方法传递给props 中的每个产品。当产品调用它时,它会从浏览器中获取数据(您将在组件逻辑的选择器中编写类似onSelect={_ =&gt; props.changeProductType(props.name, props.type, newType)} 的内容)。然后它在最初定义的范围内执行(即顶级组件)。

在那里,它重新定义了其新旧产品数组的状态(上面changeProductType 中相当不漂亮的插值),将其从一个数组中删除并添加到另一个数组中。这种状态变化将导致重新渲染,并且新的道具将被传递到这两个类别。

更简洁的解决方案是保持统一的产品集合处于状态,每个产品都有一个“类型”属性,并在渲染方法中将它们拆分到您的组件中。

class ParentComponent extends React.Component {
  constructor() {
    super()
    this.state = {
      products: { ... },
      ...
    }
  }

  changeProductType = (product, newType) => {
    editProduct = this.state.products.find( p => p.id === product.id )
    editProduct.type = newType
    this.setState({ products[id]: editProduct })
  }

  render() {
    let aProducts = this.state.products.filter( p => p.type === 'A' )
    ...
    return(
      <Aproducts changeProductType={this.changeProductType} products={aProducts}/>
      <Bproducts ... />
      <Cproducts ... />
    )
  }
}

这一切都有些牵强,所以如果不清楚,请告诉我。

【讨论】:

  • 我不想获取父组件中的所有项目。每个组件调用一个 API 端点来获取各自的数据
【解决方案2】:

我一直按照@Emil 和@Andrew 的建议使用redux 来解决这个问题。请让我知道我所做的是否正确!

在所有类别组件中,我添加了以下内容

const mapStateToProps = state => ({
  dispatchedValue: state.dispatchComponent
});

const mapDispatchToProps = dispatch => ({
  triggerComponent: (compName) => dispatch(triggerComponent(compName))
});

export default connect(mapStateToProps, mapDispatchToProps)(Acomponent);

在选择值更改时,我调度要更新的组件名称,如下所示

handleSelectChange(value){
    // UPDATE CURRENT LIST
    ...............

    // GETTING COMPONENET NAME USING VALUE
    let component = this.mapComponenet(value)

    // UPDATE OTHER COMPONENET
    this.props.triggerComponent(component);
}

然后使用componentDidUpdate触发其他组件的API调用

componentDidUpdate(prevProps, prevState) {
    if(this.props.dispatchedValue == this.state.componentName){
      // UPDATE COMPONENET CODE
    }
}

让我知道是否存在与它相关的一些问题,或者它不应该用于这样的说法,缺点和东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多