如何从平面列表项在屏幕之间传递数据

时间:2018-12-31 04:51:45

标签: react-native react-navigation

我如何将列表项从第一屏幕传递到第三屏幕,如何将数据传递到第二屏幕而不是第三屏幕。我要达到的目的是如何在第三个屏幕上编辑列表项,并在编辑文本输入内获取数据并进行更新。顺便说一句,我正在使用平面列表项,因为不赞成使用列表视图。下面是我的代码和屏幕截图。

第一个屏幕截图 enter image description here

第二张屏幕截图 enter image description here

第三张屏幕截图 enter image description here

第一个屏幕截图编码

<div class="row align-items-center">
      <div class="col col-md-auto">
        <h1>Some big text</h1>
      </div>
      <div class="row flex-column">
        <div class="col col-md-auto">Some normal text</div>
        <div class="col col-md-auto">Some normal text</div>
        <div class="col col-md-auto">Some normal text</div>
      </div>
    </div>

第二个屏幕截图编码

class SecondScreen extends Component {
constructor(props){
    super(props);
    this.state = {
        loading: true,
        email: '',
        name: '',
        title: '',
        description: '',
        error: '',
        dataSource: [],
        isFetching: false
    }
}

onPress(item){
    this.props.navigation.navigate(
        'DetailsScreen',
        {item},
    );
}

renderItem = ({ item }) => {
    return (
        <TouchableOpacity style={{ flex: 1, flexDirection: 'row', 
marginBottom: 3}}
            onPress={() => { this.onPress(item) }}>
            <View style={{ flex: 1, justifyContent: 'center', marginLeft: 
5}}>
                <Text style={{ fontSize: 18, color: 'green', marginBottom: 
15}}>
                    {"ID - "+item.id}
                </Text>
                <Text style={{ fontSize: 18, color: 'green', marginBottom: 
15}}>
                    {"Title - "+item.title}
                </Text>
                <Text style={{ fontSize: 16, color: 'red'}}>
                    {"Description - "+item.description}
                </Text>
            </View>
        </TouchableOpacity>
    )
}

renderSeparator = () => {
    return (
        <View
            style={{height: 1, width: '100%', backgroundColor: 'black'}}>
        </View>
    )
}

ListEmptyView = () => {
    return (
        <View style={styles.container}>

            <Text style={{textAlign: 'center'}}> No job available.</Text>

        </View>

    );
}

handleBackButton = () => {
    Alert.alert(
        'Exit App',
        'Exiting the application?', [{
            text: 'Cancel',
            onPress: () => console.log('Cancel Pressed'),
            style: 'cancel'
        }, {
                text: 'OK',
                onPress: () => BackHandler.exitApp()
        },],{
            cancelable: false
        }
    )
    return true;
} 

componentDidMount(){

    this.getAvailableJob()

    BackHandler.addEventListener('hardwareBackPress', 
this.handleBackButton);
} 

getAvailableJob() {
    const headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + this.props.token
    };

    axios({
        method: 'GET',
        url: 'http://192.168.1.201:8000/api/jobs',
        headers: headers,
    }).then((response) => {
        console.log('response3',response)
        console.log('response4',this.props.token)
        this.setState({
            dataSource: response.data,
            isFetching: false
        });
    }).catch((error) => {
        console.log(error);
        this.setState({
            error: 'Error retrieving data',
            loading: false
        });
    });
}

componentWillUnmount() {
    BackHandler.removeEventListener('hardwareBackPress', 
this.handleBackButton);
}

onRefresh() {
    this.setState({ isFetching: true }, function() { this.getAvailableJob() 
});
}

render() {
    const { container, emailText, errorText } = styles;
    const { loading, email, name, error, title, description } = this.state;

    return(
        <View style={container}>
            <FlatList
                data={this.state.dataSource}
                onRefresh={() => this.onRefresh()}
                refreshing={this.state.isFetching}
                renderItem={this.renderItem}
                keyExtractor={(item, index) => index.toString()}
                ListEmptyComponent={this.ListEmptyView}
                ItemSeparatorComponent={this.renderSeparator}
            />
        </View>
    ); 
}
}

export default withNavigation(SecondScreen);

第三屏截图编码

class DetailsScreen extends React.Component {

handleBackButton = () => {
    this.props.navigation.popToTop();
    return true;
} 

componentDidMount(){
    BackHandler.addEventListener('hardwareBackPress', 
this.handleBackButton);
}

componentWillUnmount() {
    BackHandler.removeEventListener('hardwareBackPress', 
this.handleBackButton);
}

onPress(item){
    this.props.navigation.push(
        'EditDetailsScreen',
        {item},
    );
}

render() {
    const { backButton } = styles;

    let item = this.props.navigation.state.params.item;

    return (
        <View style={styles.container}>

            <View style={[styles.container2, { backgroundColor: 'yellow' }, 
styles.hiddenContainer]}>
                <Text style = { styles.TextStyle }> ID { 
this.props.navigation.state.params.item.id }</Text>
            </View>

            <Text style = { styles.TextStyle }> Title { 
this.props.navigation.state.params.item.title }</Text>
            <Text style = { styles.TextStyle }> Description { 
this.props.navigation.state.params.item.description }</Text>
                <TouchableOpacity
                    style = {styles.submitButton}
                    onPress = {() => { this.onPress(item) }}>
                    <Text style = {styles.submitButtonText}> Edit </Text>
                </TouchableOpacity>
        </View>
    );
}
}
export default withNavigation(DetailsScreen);

我可以使用邮递员进行更新,但不能在react native中进行更新,而且在邮递员中,我必须将Body设置为使用x-www-form-urlencoded而不是form-data。那么我该如何在React Native中进行更新?任何帮助将非常感激。下面是我的邮递员屏幕截图。

邮递员 enter image description here

2 个答案:

答案 0 :(得分:0)

建议使用状态容器(如react-redux),但如果您不想要:可以在

之类的props中传递一个函数。
<renderedItem update={(newVal) => this.setState({ val: newVal})}>

,然后在renderedItem中,您可以使用新值调用此函数,如下所示:

this.props.update(this.state.newVal)

答案 1 :(得分:0)

我已经使用qs.stringify(data)解决了这个问题。下面是我更新的代码。

updateJobDetails = () => {

    url = 'http://192.168.1.201:8000/api/jobs/' + this.props.navigation.state.params.item.id;

    const qs = require('qs');

    const data = {title:this.state.TextInput_Title,
                description:this.state.TextInput_Description};

    const options = {
        method: 'PUT',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': 'Bearer ' + this.props.token
        },
        data: qs.stringify(data),
        url
    }

axios(options).then((response) => {
        console.log('update response',response)
        Alert.alert(
            'Update successful',
            'Your details has been updated', [{
                    text: 'OK',
                    onPress: () => this.props.navigation.popToTop()
            },]
            ,{
                cancelable: false
            }
        )
        this.setState({
            loading: false,

        });

    }).catch((error) => {
        Alert.alert("Please Enter All the Values.");
        console.log(error);
        this.setState({
            error: 'Error retrieving data',
            loading: false
        });
    });
}

render() {

    return (
        <View style={styles.container}>

            <View style={[styles.container2, { backgroundColor: 'yellow' }, 
styles.hiddenContainer]}>
                <Text style = { styles.TextStyle }> ID { 
this.props.navigation.state.params.item.id }</Text>
            </View>

            <Text style = {styles.TextStyle2}>
                Title: 
            </Text>

                <TextInput style = {styles.input}
                    underlineColorAndroid = "transparent"
                    placeholder = "Edit Title"
                    placeholderTextColor = "#9a73ef"
                    autoCapitalize = "none"
                    value={this.state.TextInput_Title}
                    onChangeText = { TextInputValue => this.setState({TextInput_Title: TextInputValue})}/>


            <Text style = {styles.TextStyle2}>
                Description: 
            </Text>

            <TextInput style = {styles.input}
                underlineColorAndroid = "transparent"
                placeholder = "Edit Description"
                placeholderTextColor = "#9a73ef"
                autoCapitalize = "none"
                value={this.state.TextInput_Description}
                onChangeText = { TextInputValue => 
this.setState({TextInput_Description: TextInputValue})}/>

            <TouchableOpacity
                style = {styles.submitButton}
                onPress = {this.updateJobDetails}>
                <Text style = {styles.submitButtonText}> Submit </Text>
            </TouchableOpacity>
        </View>
    );
}