2016-05-18 2 views
0

Я делаю приложение, которое, как предполагается, в определенный момент выдает фид информации с заголовком, описанием и информацией о пользователе. Я делаю это в ответном нативном, это также два отдельных канала в одном представлении, которые могут переключаться между двумя вкладками, поэтому я подумал, что моя текущая архитектура впоследствии будет оптимальной.Проблемы с компонентами lifecycles/не могут обрабатывать undefined

Проблема под рукой:

От Methods.js:

exports.getFriendFeed = function(TOKEN) { 
    return new Promise((resolve, reject) => { 
     fetch(baseUrl + 'feed' , { 
     method: 'GET', 
     headers: { 
     'Accept': 'application/json', 
     'Content-Type': 'application/json', 
     'Token' : TOKEN, 
     }, 
    }) 
    .then((response) => response.text()) 
    .then((responseText) => { 

     resolve(responseText); 
    }) 
    .catch((error) => { 
     reject(error); 
    }); 
    }); 
}; 

Я пишу выборки запрос и отправить его на мой экран home.js. И обработайте его следующим образом:

var Home = React.createClass({ 
. 
. 
. 
    changeComponent: function(component) { 
    Method.getFriendFeed(this.state.tokenSupreme) 
    .then((res) => this.setState({ 
     friendFeed: JSON.parse(res).friendPosts, 
     loaded: true, 
    })) 
    .catch((error) => console.log(error)) 
    .done();  
    this.setState({ 
     componentSelected: component, 
    }) 
    }, 

Это означает, что, когда я нажимаю на определенный канал, контент специально загружается для этого вида.

Rendering компонента и прохождение реквизита информационного сырья и является ли он или нет загружен:

renderComponent: function(component) { 
     if(component === 'One') { 
     return <ComponentOne 
     friendData={ 
      this.state.friendFeed 
     } 
     loaded={ 
      this.state.loaded 
     } /> 
     } else if(component === 'Two') { 
     return <ComponentTwo /> 
     } 
    }, 

Но теперь наступает реальную проблему. Следуя документации, предоставленной React Native. У меня есть console.log 'ed rowData, уступающий «загрузка», а затем возвращает данные формата json, которые я хочу. Таким образом, это означает, что он сначала успешно проходит через функцию changeComponent и становится «загружаемой», и ошибочно превращает this.state.loaded в true, это означает, однако, что во время этого выполнения есть момент времени, когда я не могу вызывать какие-либо конкретные ключи или имена в мой json из-за того, что он имеет только «вид», загруженный, который просто возвращает неопределенные и красные экраны приложения сразу.

var ComponentOne = React.createClass({ 
    getInitialState: function() { 
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    return { 
     dataSource: ds.cloneWithRows(this.props.friendData), 
    }; 
    }, 

    render: function() { 
    if (!this.props.loaded) { 
     return this.renderLoadingView(); 
    } else { 
    return (
     <ListView 
      dataSource={this.state.dataSource} 
      renderRow={this.renderRow} 
      style={styles.card} /> 
    ) 
    } 
    }, 
    renderLoadingView: function() { 
    return ( 
     <View style={{alignItems: 'center', alignSelf: 'center', marginTop: 150, justifyContent: 'center'}} > 
     <Text style={{fontSize: 30, fontWeight: '400', color: '#666'}}> Loading ... </Text> 
     </View> 
    ); 
    }, 

    renderRow: function(rowData) { 
    return (
     <CardView 
      name={rowData.name} 
      fullname='xyz' 
      distance='xyz' 
      title={rowData.title} 
      message={rowData.description} 
      score='xyz' 
      stars='xyz' 
      starcolors={colors.General.black} 
      vouched="Example" /> 
    ) 
    } 
}) 

Почему это дает мне это? Это никогда не срабатывает, если я помещу сборщик в componentDidMount, и если я поместил его в рендер, он будет стрелять бесконечно.

Как я могу более эффективно контролировать эту проблему исполнения/жизненного цикла? Я также попытался сделать это заявление IF, говорящее if (this.props.friendFeed.friend.name !== undefined), но верьте этому или нет, он просто возвращает красный экран, говорящий this.props.friendFeed.friend.name is undefined. Может ли это быть проблемой, вызывающей объект внутри ключа? Могу ли я назвать такую ​​вещь, если она не определена до ее определения?

ответ

0

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

{ 
    foo: { 
    bar: 'text' 
    } 
} 

Если в любой момент foo является undefined, вы не можете проверить, если ключ к югу от объекта также undefined. Вам нужно определить самый высокий корневой объект, который может быть не определен при загрузке данных.

Итак, это заявление не сработало: if (foo.bar !== undefined), если foo - undefined. Однако это утверждение будет в порядке: if (foo.hasOwnProperty('bar')) или технически даже if (foo !== undefined).

Что касается вашей основной проблемы, я предполагаю, что происходит что-то асинхронное с анализом данных. Вот как я реализую fetch ...

function checkStatus(response) { 
    if (response.status >= 200 && response.status < 300) { 
    return response.text().then((text) => { 
     if (text == "") return "" 
     return JSON.parse(text) 
    }) 
    return response.json() 
    } 
} 

get(id, query) { 
    let url = this.API_URL() + '/' + id + this._generateQuery(query) 
    return fetch(url, { 
    method: 'get', 
    headers: this._headers() 
    }).then(this._checkStatus) 
    .then((data) => { 
     return data 
    }) 

}

Обратите внимание, как я должен подключиться к обещанию стороне обработки тела в текст. Я бы попытался сделать что-то подобное в вашем changeComponent, чтобы он не вызывал setState (а затем устанавливал загрузку в true), пока не убедитесь, что данные разобраны. Поскольку он является встроенным, он может сразу вызвать setState, а затем на короткое время отобразить компонент с неполными данными, пока он завершит разбор (поскольку он просто передает ссылки на переменные, а не значения).

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