ReactJS中处理复杂数据结构的最佳实践

3

我正在将React集成到一个现有应用程序中。这个应用程序是数据密集型的,数据结构相当复杂,这使得我有点难以适应React模式,特别是无状态和组合。

给定这样的数据:

component: {
  options: [optionA, optionB, optionC]
}

options: {
  optionA : {
    name: 'FOO',
    choices: [choiceA, choiceB, choiceC]
  },
  optionB : {
    name: 'BAR',
    choices: [choiceD, choiceE]
  },
  ...
}

choices: {
  choiceA : {
    type: 'typeA',
    choices: [choiceA, choiceB, choiceC],
    name: 'abb'
  },
  choiceB : {
    type: 'typeB',
    name: 'abc'
  },
  ...
}

由于这些数据由id链接,我有两种可能性:
  1. 在父组件中检索子组件的数据并将其传递给子组件。

  2. 传递ID,子组件检索自己的数据。

其中一种意味着动态检索组件道具,另一种意味着拥有一个“上帝”父级,该父级拥有其子级所需的所有必要数据,哪种方法更好?
我的另一个问题是,如果以Choice作为其道具的组件应根据其Choice的类型显示不同,则更好的方法是制作像这样的包装器组件吗?:

class Choice extends Component {
  constructor(props){
    super(props);
  }
  
  render(){
    switch(props.choice.type){
       case "typeA":
         return (<TypeAComponent />);
       case "typeB":
         return (<TypeBComponent />);
       default:
          return (..);
    }
  }
}

还有没有更简洁的替代方法(我对 switch 语句有点过敏)...

1个回答

4

关于第一个问题:

我会选择第一种解决方案,即在父级中检索数据。如果您选择使用某种状态管理(redux),这将使操作变得更加容易(只需在一个地方处理即可)。

关于第二个问题:

您可以使用字典来替换开关语句:

const choiceRenderers = {
    "typeA": () => <TypeAComponent />,
    "typeB": () => <TypeBComponent />,
    // etc.
};

class Choice extends Component {
    render() {
        const renderer = choiceRenderers[this.props.choice.type];
        return renderer
            ? renderer()
            : <DefaultChoice />;
    }
}

潜在优势在于,这种选择-组件映射可以在多个组件之间共享而无需进行复制,您只需将其存储在模块中,需要时导入即可。

谢谢,这证实了我的想法!关于转移到Redux,您认为它是否适用于深度链接的数据结构? - Malo Guertin
1
根据redux的创始人 Dan Abramov 的说法,它与浅层状态树更配套。关于更多信息,我强烈推荐他的 egghead 课程,这是一个学习所有相关知识的绝佳资源。 - Dan Homola

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接