反应:-父组件引用子组件的状态

时间:2020-02-08 13:25:29

标签: reactjs

我对React还是很陌生,并且正在尝试找出构建支持灵活的多语言信息的表单组件的最佳方法。

要在服务器端处理翻译,String属性已由Translation对象属性替换,该属性提供了一种灵活的方法来支持需要/可用的字段内容的尽可能多的翻译。当数据作为JSON来自服务器时,它遵循相同的对象设计并采用嵌套格式(为示例目的而简化):

{"book": {
    "id": 1,
    "isbn": "978-1853260414",
    "name": {
        "translation": {
            "id": 100,
            "usage": "Book name",
            "translationContents":
            [
                {"id": 2000, "language": "EN", "content": "The Great Gatsby", "status":10},
                {"id": 2001, "language": "ES", "content": "El gran Gatsby", "status":20},
                {"id": 2002, "language": "FR", "content": "Gatsby le magnifique", "status":10}
            ]
        }
    },
    "synopsis": {
        "translation": {
            "id": 101,
            "usage": "Book synopsis",
            "translationContents":
            [
                {"id": 2003, "language": "EN", "content": "A consummate summary of the roaring twenties", "status":10},
                {"id": 2004, "language": "ES", "content": "Un resumen consumado de los locos años veinte", "status":10},
                {"id": 2005, "language": "FR", "content": "Un résumé parfait des années folles", "status":30}
            ]
        }
    }
}}

在React中,我需要创建一个组件,该组件允许用户以一种形式编辑所有数据,即

  • ISBN(isbn)
  • 名称用法(name.translation.usage)
  • 名称内容EN(name.translation.translationContents [0] .content)
  • 名称状态EN(name.translation.translationContents [0] .status)
  • 命名内容ES(name.translation.translationContents [1] .content)
  • 名称状态ES(name.translation.translationContents [1]。状态)
  • 名称内容FR(name.translation.translationContents [2] .content)
  • 名称状态FR(name.translation.translationContents [2] .status)
  • 提要用法(synposis.translation.usage)
  • 简介内容EN(synposis.translation.translationContents [0] .content)
  • 简介状态EN(synposis.translation.translationContents [0] .status)
  • 简介内容ES(synposis.translation.translationContents [1] .content)
  • 提要状态ES(synposis.translation.translationContents [1] .status)
  • 简介内容FR(synposis.translation.translationContents [2] .content)
  • 提要状态FR(synposis.translation.translationContents [2] .status)

从理论上讲,我认为我可以为JavaScript对象采用与JSON相同的结构。

然后使用React创建可重复使用的Translation和TranslationContent组件,以构建表单输入字段:

<Book>
   <TextField> // ISBN
   <Translation> // Name
      <TranslationContent /> // EN
      <TranslationContent /> // ES
      <TranslationContent /> // FR
   </Translation>
   <Translation> // Synposis
      <TranslationContent /> // EN
      <TranslationContent /> // ES
      <TranslationContent /> // FR
   </Translation>
</Book>

这是可能的,但是我在React State遇到了绊脚石。我需要Book保留对其Translation子元素的属性值的引用(而Translation保留其TranslationContent子元素的属性值的引用),以便Book最终可以将所有更新的属性发布回服务器。

通过道具引用对象

我尝试通过道具将JavaScript对象从Book传递到Translation:

<Translation data={this.nameTranslationData} />

在翻译构造函数中:

constructor(props, context) {
    super(props, context);
    this.state = props.data;
}

我的期望是,当子Translation对象更新其State属性时,它会在父Book上自动更新,因为它们指向同一JavaScript对象。但是,这不会发生,并且似乎转换状态会创建props.data对象的副本,因此对转换状态属性的更改将保留在转换范围内,并且不会反映在Book父属性this.nameTranslationData中。

通过道具回调

到目前为止,我发现的唯一方法是为Book中的每个字段创建一个回调方法,例如

nameTranslationStateCallBack=(updatedTranslationState)=>{this.nameTranslationData=translationState;};

...并通过道具将其传递给Translation子代:

<Translation data={this.nametranslationData} sendStateToParentCallback={this.nameTranslationStateCallBack} />

..并且每次我在“翻译”子级“组件”表单字段中检测到更改时,它都会将其状态的副本发送回父级:

this.props.sendStateToParentCallback(this.state);

然后在Translation及其TranslationContent子组件之间必须存在相同的功能。

但是,这似乎是一堆乱七八糟的重复代码,并且在具有许多翻译字段的较大形式上,它正在创建许多回调方法,我担心这样也可能无效地将更新级联到父级。这就是为什么子组件的状态与父组件的引用是同一对象的原因。

由于我是React的新手,有可能我完全以错误的方式解决了这个问题,或者错过了一个明显的解决方案。我将对如何最好地构造此结构的任何建议表示感谢,因为一旦采用一种方法,它将在整个应用程序中使用。

非常感谢。

0 个答案:

没有答案