javascript - 在 React 组件中渲染之前操作数据
问题描述
有了 React 的 Angular 背景,我无法在渲染数据之前就如何操作和重组数据。假设我将此对象从父组件传递给子组件:
{
"_id": "5c716c53591610007f6d44ef",
"model": {
"_id": "5c7166eb591610007f6d44d4",
"name": "E 300"
},
"serie": {
"_id": "5c716ba0591610007f6d44e2",
"name": "E-Class"
}
},
{
"_id": "5c716c60591610007f6d44f2",
"model": {
"_id": "5c7166f2591610007f6d44d6",
"name": "E 220"
},
"serie": null
},
{
"_id": "5c716c6a591610007f6d44f3",
"model": {
"_id": "5c7166fe591610007f6d44d8",
"name": "C 180"
},
"serie": {
"_id": "5c716ba4591610007f6d44e3",
"name": "C-Class"
}
},
{
"_id": "5c716c6e591610007f6d44f4",
"model": {
"_id": "5c716702591610007f6d44d9",
"name": "C 200"
},
"serie": {
"_id": "5c716ba4591610007f6d44e3",
"name": "C-Class"
}
},
{
"_id": "5c716c74591610007f6d44f5",
"model": {
"_id": "5c716705591610007f6d44da",
"name": "C 220"
},
"serie": {
"_id": "5c716ba4591610007f6d44e3",
"name": "C-Class"
}
}
我想将每个型号名称归类到它们的系列下。 例如 C-Class: ['E300', 'E220'] 等,并将没有定义系列的模型放入对象 NoClass。
对于内联 jsx 来说太多了(至少看起来如此 ??)所以我需要一些辅助函数,但我无法进行操作,因为每次我收到数据未定义的错误,这意味着它会尝试渲染在它出现并被修改之前的代码。
所以我非常想将数据过滤成新的对象,然后渲染这些而不是原始的道具数据。而且在渲染之前我不知道该怎么做
我目前内联的尝试 - 它确实呈现但它不检查空系列对象并在超过 1 个不同系列时中断:
class ModelSelect extends React.Component {
render() {
const { models } = this.props
return (
models && <div className={"ModelSelect_Wrapper"}>
<Select placeholder={"Model"} loading={models.loading} disabled={models.data.length === 0}>
{_.uniqBy(models.data, 'name').map((serie) =>
<OptGroup label={serie.serie.name}>
{!models.loading && models.data.map((model, index) =>
<Option value={model.model._id} key={index}>{model.model.name}</Option>
)}
</OptGroup>
)}
</Select>
</div>
);
}
解决方案
最简单的方法是使用商店。您有几个可用的选项,例如Redux
、Flux
和Mobx
。不幸的是,学习使用 Stores 有点困难。来自 angular,我会将商店$scope
与 angular.js 1x 进行比较,不同之处在于没有魔法导致视图重新渲染,您必须依靠反应检测道具的变化才能发生重新渲染。这个想法是 store 是一个数据结构,当它被修改时,使用 store 作为 prop 的组件将被重新渲染。这非常有用,尤其是在您异步获取数据时。
基本模式是
- 用于
componentDidMount()
加载高阶组件中的数据 - 转换数据并使用新数据更新存储
- 您正在将商店传递给您的组件,例如
<MyComponent store={store} />
- 加载数据时,将存储传递给子组件
这样做你的组件可能看起来像
class MyComponent extends React.Component {
static defaultProps = {
store:{}
}
state = {
loading: true
}
componentDidMount() {
this.props.store.loadSomeData().then(()=>this.setState({loading:false}));
}
render(){
return this.state.loading ? null : <MyChildComponent store={store} />
}
}
请记住,您负责加载和转换商店中的数据,这只是您的组件如何显示加载和接收转换后的数据的概括概述。您的确切方法将根据您使用的商店而大不相同。
我的回答再具体不过了,因为要涵盖的内容太多了,而且所需工作的范围因您使用的库而异。例如,mobx-3x 你所做的就是用它来装饰你的组件,@inject
它会为你@observer
处理shouldComponentUpdate()
实现。
所以你的第一步是选择一家商店,然后从那里去。祝你好运。
推荐阅读
- xml - 使用 xslt 转换 XML Soap
- java - Hackerrank 稀疏数组
- google-bigquery - BigQuery - 如何将 00:00:00 UTC 添加到现有时间戳?
- java - 如何使用 navController 通过 popBack 返回根目录
- r - 如何在while循环中重复特定数字并将它们附加为R中的数字
- python - 如何使用 .bat 文件激活虚拟环境?
- python-asyncio - 如何使用异步dask客户端
- angular - 依赖于根级导入的 LazyLoaded 模块是否需要导入依赖项?
- api - 如何使用power bi desktop调用power bi api来访问来自Power BI服务的内容
- java - 使用 JPanel 显示不同的信息,但只能显示第一次