编辑:我也在努力了解我应该采用什么样的结构以及如何在组件之间传递导航器等。如果您对我的代码有任何批评或反馈,也将受到高度赞赏!
所以我正在尝试从我的PHP API(接受POST数据并返回JSON)创建新闻源。 JSON:
{"status":"OK","news":[{"header":"some header","text":"some text"},{"header":"some other header","text":"some other text"},{"header":"yet another header","text":"some even more text"}]}
我想将此JSON提取到我的React Native应用程序中,并将每个新闻帖子写为视图。这个想法几乎就是一个博客。目前我试图做的事情不起作用。我可以成功获取JSON,但是,我不知道如何成功地将get_news()
中的Main_logic.js
中的JSON成为render()
中的index.ios.js
并打印出每个新闻帖子作为一个单独的视图元素。任何帮助都会非常感激!
这是我的index.ios.js中的render函数:
render(){
//Components
const Header = (
<TouchableHighlight
onPress={() => this.toggleSideMenu()}
style={this.state.login_button_press ? styles.hamburger_pressed : styles.hamburger}
onHideUnderlay={this._onHideUnderlay.bind(this)}
onShowUnderlay={this._onShowUnderlay.bind(this)}
>
<View>
<Icon
name='menu'
color='#FFFFFF'
size={40}
/>
</View>
</TouchableHighlight>
)
const ContentView = (
<Navigator
initialRoute={{id: 'news'}}
configureScene={this._configureScene}
renderScene={(route, navigator) => {
//Inloggningssidan
if(route.id === "login"){
return(
<View style={{opacity: this.state.opacity}, styles.container}>
<Image resizeMode="center" style={styles.logo} source={require('./app/res/mbab_cmyk.png')} />
<TextInput
placeholder="Namn"
autocorrect={false}
style={styles.text_box}
onChangeText={(username) => {{GLOBALS.USERNAME = username}}}
returnKeyType="next"
onSubmitEditing={(event) => {
this.refs.password.focus();
}}
/>
<TextInput
ref="password"
placeholder="Lösenord"
autocorrect={false}
secureTextEntry={true}
style={styles.text_box}
onChangeText={(password) => {{GLOBALS.PASSWORD = password}}}
returnKeyType="go"
/>
<TouchableHighlight style={styles.login_button} onPress={() => MainLogic.login(navigator)}>
<Text style={styles.button_text}>Logga in</Text>
</TouchableHighlight>
</View>
);
}
else if(route.id === "news"){
var news = MainLogic.get_news();
return(
<ScrollView style={{opacity: this.state.opacity}, styles.scroll_container}>
<Text style={styles.empty_text}>{news}</Text>
</ScrollView>
);
}
//Test sida
else{
return(
<View style={styles.container}>
{Header}
<Text>TEST</Text>
<TouchableHighlight style={styles.button}>
<Text>Tryck på mig</Text>
</TouchableHighlight>
</View>
);
}
}
}
/>
)
//App
return (
<View style={{backgroundColor: "#093360", flex: 1}}>
<View style={{flex: 1, marginTop: 20}}>
<StatusBar
barStyle={"light-content"}
/>
<SideMenu
isOpen={this.state.sidemenu_is_open}
style={styles.menu}
menu={<this.Menu navigator={navigator}/>}
>
<View style={styles.header_bar}>
{Header}
</View>
{ContentView}
</SideMenu>
</View>
</View>
);
}
我还尝试将代码拆分为组件,以使其保持令人愉快的结构。 Index.ios.js:
import GLOBALS from './app/components/globals.js';
const MainLogic = require('./app/components/logic/main_logic.js');
以下是位于get_news()
(MainLogic)中的函数Main_logic.js
:
get_news: function(){
fetch(GLOBALS.API_URL, {
method: "POST",
headers: {
'Accept': 'application/x-www-form-urlencoded',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: "function=news&username=" + GLOBALS.USERNAME + "&password=" + GLOBALS.PASSWORD,
})
.then((response) => response.json())
.then((response) => {
try{
if(JSON.stringify(response.status).replace(new RegExp('"', 'g'), '').match("OK")){
GLOBALS.NEWS = response;
}
else{
return "FEL";
}
}
catch(e){
AlertIOS.alert("error", e.message);
}
})
.catch((e) => {
console.warn(e);
})
.done();
}
修改:回应amb:
news.js:
import React, { Component } from 'react';
import {
View,
Text,
TouchableHighlight,
ListView,
} from 'react-native';
import styles from './styles.js';
import GLOBALS from './globals.js';
const MainLogic = require('./logic/main_logic.js');
export default class News extends Component{
constructor (props) {
super(props)
this.state = { news: [] }
}
componentDidMount(){
// Modify your function to return a promise instead of a value
MainLogic.get_news().then(response => {
// setState will trigger a render with the received data
this.setState({news: response});
})
}
_renderRow(rowData, sectionID, rowID, highlightRow){
return (
<View>
<Text>{rowData}</Text>
</View>
)
}
render(){
return (
<ListView
dataSource={this.state.news}
renderRow={this._renderRow()}
/>
);
}
}
get_news()
中的 main_logic.js
:
get_news: async function(){
fetch(GLOBALS.API_URL, {
method: "POST",
headers: {
'Accept': 'application/x-www-form-urlencoded',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: "function=news&username=" + GLOBALS.USERNAME + "&password=" + GLOBALS.PASSWORD,
})
.then((response) => response.json())
.then((response) => {
try{
if(JSON.stringify(response.status).replace(new RegExp('"', 'g'), '').match("OK")){
return response.news;
}
else{
return "FEL";
}
}
catch(e){
AlertIOS.alert("error", e.message);
}
})
.catch((e) => {
console.warn(e);
})
.done();
}
获取错误undefined is not an object (evaluating 'allRowIDs.length')
答案 0 :(得分:1)
var news = MainLogic.get_news();
是异步调用,因此如果您不等待它完成,您的news
var中将永远不会有任何内容。
此块
var news = MainLogic.get_news();
return (
<ScrollView style={{opacity: this.state.opacity}, styles.scroll_container}>
<Text style={styles.empty_text}>{news}</Text>
</ScrollView>
);
绝不会提供任何新闻。
您应该做的是拥有一个调用get_news
函数的组件,并在响应到达时更改其状态。以此伪代码为例,按照注释注释:
class News extends React.Component {
constructor (props) {
super(props)
this.state = { news: [] }
}
componentDidMount () {
// Modify your function to return a promise instead of a value
MainLogic.get_news().then(response => {
// setState will trigger a render with the received data
this.setState({news: response})
}
}
render () {
// You should use ListView instead of ScrollView, because
// this.state.news will be an array and it can't be displayed
// in a Text component.
return (
<ScrollView style={{opacity: this.state.opacity}, styles.scroll_container}>
<Text style={styles.empty_text}>
{this.state.news}
</Text>
</ScrollView>
)
}
}