编辑: 我也在努力理解我应该采用什么样的结构以及我应该如何在组件之间传递导航器等。如果您对我的代码有任何批评或反馈,也将受到高度赞赏!
因此,我尝试从 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 应用程序中,并将每条新闻文章写为 View 。这个想法几乎就是一个博客。目前我尝试做的事情是行不通的。我可以成功获取 JSON,但是,我不知道如何从 Main_logic.js
中的 get_news()
成功获取 JSON 到 render()
在 index.ios.js
中并将每个新闻帖子打印为单独的 View 元素。任何帮助将不胜感激!
这是我的 index.ios.js 中的渲染函数:
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>
);
}
我还尝试将我的代码拆分成多个组件,以使其保持在一个令人愉快的结构中。索引.ios.js:
import GLOBALS from './app/components/globals.js';
const MainLogic = require('./app/components/logic/main_logic.js');
这是位于 Main_logic.js
(MainLogic) 中的函数 get_news()
:
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:
新闻.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()}
/>
);
}
}
main_logic.js
中的get_news()
:
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')
最佳答案
var news = MainLogic.get_news();
是一个异步调用,所以如果你不等待它完成,你的 news
将永远不会有任何内容变种。
这个 block
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>
)
}
}
关于ios - React Native - 从 fetch() JSON 渲染多个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41238259/