我是React原生的新手,说实话,我对React有一个非常基本的了解。我正在开发一个示例应用程序,其中我使用reusable components和 ES6 sintax。
在同一场景中多次重复使用同一组件时,我遇到了意外的结果(我也使用了Navigator)。更准确地说,我无法理解为什么不同组件(相同类型)显然是彼此状态的条件。
我发布了我的代码以便更好地理解。
这是我的主页,我使用相同的自定义组件< 2的2倍TopCategories /> :
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>
)
}
}
我无法理解为什么第一个&lt;的state.simplifiedCategories。 TopCategories&gt;我的HomeScene中使用的组件在第二个&lt;之后似乎是一个空数组。 TopCategories&gt;组件已呈现。到目前为止,我认为这两个组件是完全孤立的,有自己的&#34;私有&#34;州。但在这种情况下似乎是以某种方式共享。
有人可以解释这里发生了什么吗?然后我该如何解决这个问题呢?
由于
编辑2016/09/05 正如用户V-SHY所建议的那样,我试图给每个组件一个随机字符串作为键,但这并没有解决问题。 我觉得非常奇怪的是,我只能看到&lt; TopCategories&gt;在全局窗口对象中,最后一个。
此处的屏幕截图是指使用
进行的测试 <TopCategories key="tc_first" {...this.props}/>
<TopCategories key="tc_second" {...this.props}/>
HomeScene.js 文件中的
答案 0 :(得分:2)
根据Daniel的建议,在从服务器获取数据时出现了问题。特别是在 TopCategories.js 文件
中创建_topCategories =此对象时出错了_fetchContent(){
_topCategories = this; // ISSUE HERE!
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);
}
}
}
)
}
我解决了将fetchContent方法传递给组件的引用:
constructor(props) {
super(props);
this.state = {categories: []};
this._fetchContent(this); // passing THIS reference
}
_updateCategoriesList(rawCategories){
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(instanceRef){
motifConnector.call(
"CATEGORY",
"FindTopCategories",
{},
function(err, json){
if(err!=null) utility.log("e", err);
else {
try{
instanceRef._updateCategoriesList(json.res.header.body.CatalogGroupView);
}catch(err){
utility.log("e", err);
}
}
}
)
}