【发布时间】:2017-01-12 05:06:21
【问题描述】:
我是 React Native 的新手,老实说,我对 React 有非常基本的了解。我正在开发一个使用reusable components 和ES6 sintax 的示例应用程序。
在同一个场景中多次重用同一个组件时,我遇到了意想不到的结果(我也使用了 Navigator)。更准确地说,我无法理解为什么不同的组件(相同类型)显然是彼此状态的条件。
我发布我的代码是为了更好地理解。
这是我的主页,我在其中使用了 2 次相同的自定义组件 :
HomeScene.js
import React from 'react';
import {View} from 'react-native';
import BaseScene from './BaseScene'
import SearchSuggest from '../components/SearchSuggest';
import TopCategories from '../components/TopCategories'
import styles from '../styles'
export default class HomeScene extends BaseScene {
render() {
return(
<View style={styles.container}>
<SearchSuggest
navigator={this.props.navigator}
/>
<TopCategories/> //first
<TopCategories/> //second
</View>
)
}
}
这些是使用的内部组件的详细信息:
TopCategories.js
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet
} from 'react-native';
import styles from '../styles'
import utility from '../utility'
import serverConnector from '../serverConnector'
import routes from '../routes'
import MenuItemComplex from './MenuItemComplex'
export default class TopCategories extends Component {
constructor(props) {
super(props);
this.state = {categories: []};
this._fetchContent();
}
_updateCategoriesList(rawCategories){
//store in state.categories array a simplied version of
//the contents received from the server
let simplifiedCategories = [];
for(i=0; i<rawCategories.length; i++){
var simpleCat = {};
simpleCat.id = rawCategories[i].uniqueID;
simpleCat.name = rawCategories[i].name;
simplifiedCategories.push(simpleCat);
}
this.setState({categories: simplifiedCategories });
}
_fetchContent(){
//fetch content from server in JSON format
_topCategories = this;
serverConnector.call(
"CATEGORY",
"FindTopCategories",
{},
function(err, json){
if(err!=null) utility.log("e", err);
else {
try{
_topCategories._updateCategoriesList(json.res.header.body.CatalogGroupView);
}catch(err){
utility.log("e", err);
}
}
}
)
}
openCategoryScene(id, name){
//push on Navigator stack the next route with additional data
let nextRoute = routes.get("categoriesListFirst");
nextRoute.passProps = {
categoryId: id,
categoryName: name
};
this.props.navigate(nextRoute)
}
render(){
console.log(this.state)
return (
<MenuItemComplex key="categories" name="Catalogo" icon="list-b" onItemSelected={this.openCategoryScene.bind(this)} subItems={this.state.categories} />
)
}
}
最后 MenuItemComplex.js
import React, { Component } from 'react';
import { View, Text, Image, TouchableHighlight, TouchableWithoutFeedback } from 'react-native';
import styles from '../styles'
export default class MenuItemComplex extends Component{
static propTypes = {
name : React.PropTypes.string.isRequired,
icon : React.PropTypes.string.isRequired,
subItems: React.PropTypes.array.isRequired,
onItemSelected: React.PropTypes.func.isRequired
};
render(){
let subItems = [];
for(i=0; i<this.props.subItems.length; i++){
let subItem = this.props.subItems[i];
subItems.push(
<TouchableHighlight
key={subItem.id}
underlayColor={"#d00"}
activeOpacity={1}
onPress={() => this.props.onItemSelected(subItem.id, subItem.name)}
>
<View style={styles.menuSubItem}>
<Text style={[styles.mmText, styles.menuSubItemText]} >
{subItem.name}
</Text>
</View>
</TouchableHighlight>
)
}
return(
<View>
<TouchableWithoutFeedback disabled={true}>
<View style={styles.menuItem}>
<Image style={styles.menuItemImage} source={{uri: this.props.icon}} />
<Text style={[styles.mmTextBold, styles.menuItemText]}>{this.props.name}</Text>
</View>
</TouchableWithoutFeedback>
{subItems}
</View>
)
}
}
我不明白为什么在我的 HomeScene 中使用的第一个 组件的 state.simplifiedCategories 在第二个 组件渲染后似乎是一个空数组。到目前为止,我认为这两个组件是完全隔离的,具有自己的“私有”状态。但在这种情况下,似乎这是以某种方式共享的。
有人可以解释这里发生了什么吗?然后我该如何解决呢?
谢谢
编辑 2016/09/05
正如用户 V-SHY 所建议的,我试图给每个组件一个随机字符串作为键,但这并不能解决问题。
我觉得很奇怪的是,在全局窗口对象中,我只能看到
这里的截图指的是用
做的测试 <TopCategories key="tc_first" {...this.props}/>
<TopCategories key="tc_second" {...this.props}/>
在 HomeScene.js 文件中
【问题讨论】:
-
尝试为 HomeScene 中的
组件提供不同的键?并尝试为 TopCategories render() 中的 MenuItemComplex 组件提供动态键而不是“类别”的常量键?好像,当第二个 组件开始渲染时,第一个 组件的状态被重置,您使用相同的键渲染两个 MenuItemComplex 组件,我想知道这是您问题的根源。 -
嗨 V-SHY,我尝试了你的建议但没有成功。特别是我试图给每个子组件一个随机字符串作为键,但这并不能解决问题。我正在更新原始问题,添加有关 console.log(window) 的信息
-
如果它们有单独的键,则不会发生这种行为,尤其是当文件本身没有变量时。我建议给他们一个不同的 prop 值来区分它们,然后添加 console.logs 来调试正在发生的事情。我建议这是数据获取或突变的问题。
-
谢谢@DanielSchmidt!这确实是一个与从服务器获取数据机制有关的问题。我正在用问题和我的解决方案更新问题
-
@AndreaDiLisio 太棒了!
标签: reactjs react-native