我是 React Native 的新手,说实话,我对 React 只有非常基本的了解。我正在开发一个示例应用程序,其中使用 reusable components和 ES6 语法。
在同一场景中多次重复使用同一组件时,我遇到了意外的结果(我还使用了导航器)。更准确地说,我无法理解为什么不同的组件(同一类型)显然是彼此规定的条件。
我发布我的代码是为了更好地理解。
这是我的主页,其中我使用了两次相同的自定义组件< 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>
)
}
}
我不明白为什么在我的 HomeScene 中使用的第一个
有人可以解释一下这里发生了什么吗?那我该如何解决这个问题呢?
谢谢
编辑2016/09/05
根据用户 V-SHY 的建议,我尝试为每个组件提供一个随机字符串作为 key ,但这并不能解决问题。
我觉得很奇怪的是,我在全局窗口对象中只能看到
此处的屏幕截图是指使用 进行的测试
<TopCategories key="tc_first" {...this.props}/>
<TopCategories key="tc_second" {...this.props}/>
在HomeScene.js文件中
最佳答案
根据 Daniel 的建议,从服务器获取数据期间出现问题。特别是在 TopCategories.js 文件中创建 _topCategories=this 对象时我错了
_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);
}
}
}
)
}
关于reactjs - React Native : this. 可重用组件的状态不是预期的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39320230/