2016-10-11 3 views
0

Я довольно новичок в React-native, поэтому легко на меня! :)React-native глобальная переменная undefined

Я создаю приложение, которое использует несколько больших объектов json для своих основных данных, которые должны быть доступны и обновляться через несколько компонентов. Я достиг этого, но обнаружил, что данные видны только для всех компонентов, если я принудительно привязываю объект к массиву. т.е.

global.a1['XX']=data.movies; // This works fine 
global.a2=data.movies; // This is undefined in other components. 

Это работает, но я не понимаю, почему так хочется, чтобы понять, что происходит перед созданием приложения.

Заранее за вашу помощь.

Пример кода ниже:

Файл: global.js

var a1 = new Object(); 
var a2 = new Object(); 
module.exports = { a1, a2 } 

Файл: select.js

'use strict'; 
import React, { Component,PropTypes } from 'react'; 
import { Text} from 'react-native'; 
import * as global from './global'; 
class Select extends Component { 
    render() { 
    console.log("a1:"+global.a1['XX'][0].title); // Ok 
    console.log("a2:"+global.a2[0].title); // Fails with undefined is not an object 
    return (<Text>{global.a1['XX'][0].title} {global.a2[0].title}</Text>); 
}} 
export default Select; 

Файл: index.android.js

var API_URL = 'http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json'; 
var PARAMS = '?apikey=7waqfqbprs7pajbz28mqf6vz&page_limit=2'; 
import React, { Component,PropTypes } from 'react'; 
import { AppRegistry,Text} from 'react-native'; 
import * as global from './global'; 
import Select from './select'; 

class test extends Component { 
    constructor(props) { 
    super(props); 
    this.state = {loaded: false}; 
    } 
    componentDidMount() { 
    fetch(API_URL+PARAMS) 
     .then((response) => { return response.json() }) 
     .then((responseData) => { return responseData; }) 
     .then((data) => { 
     global.a1['XX']=data.movies; 
     global.a2=data.movies; 
     this.setState({loaded: true}); 
     }) 
     .done(); 
    } 

    render() { 
    if (!this.state.loaded) { return (<Text>Loading...</Text>);} 
    console.log("a1:"+global.a1['XX'][0].title); // This works 
    console.log("a2:"+global.a2[0].title); // This works 
    return (<Text><Select/></Text>); 
    } 
} 
AppRegistry.registerComponent('test',() => test); 

ответ

1

В одном случае вы изменяете n существующая переменная (по ссылке), в другой вы изменяете локальную привязку значения.

Когда import * as global from './global' вы фактически создавая локальный объект, указывающий на значения экспортируемых из ./global, немного, как если бы вы сделали:

let global = { 
    a1: {}, 
    a2: {} 
} 

Затем вы добавляете к объекту определяется как a1 под свойство XX, это означает, что вы меняете исходный объект. НО, когда вы делаете global.a2 = ..., вы не меняете существующий объект, вы заменяете локальную ссылку a2, чтобы указать на что-то другое, это изменение не покинет ваш текущий модуль, и поэтому ваш select.js не знает о ваших изменениях.

Если у вас возникнут проблемы с React, если вы измените содержимое своих объектов, скорее вы должны их переопределить, но это еще одна тема, которую вы скоро обнаружите (неизменность).

+0

Спасибо FMC, это имеет смысл, но если добавление ['XX'] создает локальную копию, почему данные доступны в компоненте Select? Второй вопрос: как лучше всего обрабатывать объекты, которые необходимо обновлять несколькими компонентами? – Railton

+0

Это не локальная копия, это локальная ссылка на объект, добавление свойства 'XX' к объекту сохраняет ссылку на объект и, таким образом, изменяет оригинал. Если вы переопределяете 'global.a2', вы локально теряете ссылку на исходный объект и, следовательно, не отражаете никаких изменений в источнике. – FMCorz

Смежные вопросы