如何通过reactnavigation v5将参数从一个屏幕传递到另一个屏幕

时间:2020-06-02 21:00:00

标签: javascript reactjs react-native

我有一个问题:这里是用户列表,我想向任何用户添加约会,因此在用户屏幕上,添加约会屏幕上有一个PlusButton发送用户(从用户屏幕的headerRight呈现的PlusButton)。但是我不知道如何传递给AddAppointmentScreen用户ID,因为链接到屏幕不是通过按钮,而是通过react-navigation v5。

这是我在github上的项目的link

App.js

const HeaderRight = ({ navigation, target }) => {
    return (
        <Button transparent onPress={() => navigation.navigate(target)}>
            <Icon name='plus' type='Entypo' style={{ fontSize: 26 }} />
        </Button>
    )
}


<Stack.Screen
                name='Patient'
                component={PatientScreen}
                options={{
                    title: 'Карта пациента',
                    headerTintColor: '#2A86FF',
                    headerTitleAlign: 'center',
                    headerTitleStyle: {
                        fontWeight: 'bold',
                        fontSize: 20,
                    },
                    headerBackTitleVisible: false,
                    headerRight: () => <HeaderRight navigation={navigation} target={'AddAppointment'} />,
                }}
/>

AddAppointmentScreen.js

import React, { useState } from 'react'
import { Keyboard } from 'react-native'
import { Container, Content, Form, Item, Input, Label, Icon, Text, Button } from 'native-base'
import DateTimePicker from '@react-native-community/datetimepicker'
import styled from 'styled-components/native'

import { appointmentsApi } from '../utils/api'

const AddAppointmentScreen = ({ route, navigation }) => {
    const [values, setValues] = useState({ patientId: route.params?.patientId._id ?? 'defaultValue' })
    const [date, setDate] = useState(new Date())
    const [mode, setMode] = useState('date')
    const [show, setShow] = useState(false)

    console.log(values.patientId)
    //I need to get patientId in this screen to create appointment to THIS user with its ID

    const setFieldValue = (name, value) => {
        setValues({
            ...values,
            [name]: value,
        })
    }

    const handleChange = (name, e) => {
        const text = e.nativeEvent.text
        setFieldValue(name, text)
    }

    const submitHandler = () => {
        appointmentsApi
            .add(values)
            .then(() => {
                navigation.navigate('Patient')
            })
            .catch((e) => {
                alert(e)
            })
        /* alert(JSON.stringify(values)) */
    }

    const formatDate = (date) => {
        var d = new Date(date),
            month = '' + (d.getMonth() + 1),
            day = '' + d.getDate(),
            year = d.getFullYear()

        if (month.length < 2) month = '0' + month
        if (day.length < 2) day = '0' + day

        return [year, month, day].join('-')
    }

    const onChange = (event, selectedDate) => {
        Keyboard.dismiss()
        const currentDate = selectedDate || date
        const date = formatDate(currentDate)
        const time = currentDate.toTimeString().split(' ')[0].slice(0, 5)
        setShow(Platform.OS === 'ios')
        setDate(currentDate)
        setValues({
            ...values,
            ['date']: date,
            ['time']: time,
        })
    }

    const showMode = (currentMode) => {
        show ? setShow(false) : setShow(true)
        setMode(currentMode)
    }

    const showDatepicker = () => {
        Keyboard.dismiss()
        showMode('datetime')
    }

    return (
        <Container>
            <Content style={{ paddingLeft: 20, paddingRight: 20 }}>
                <Form>
                    <Item picker style={{ borderWidth: 0 }} /* floatingLabel */>
                        <Input
                            onChange={handleChange.bind(this, 'dentNumber')}
                            value={values.dentNumber}
                            keyboardType='number-pad'
                            clearButtonMode='while-editing'
                            placeholder='* Номер зуба'
                        />
                    </Item>
                    <Item picker>
                        <Input
                            onChange={handleChange.bind(this, 'diagnosis')}
                            value={values.diagnosis}
                            clearButtonMode='while-editing'
                            placeholder='* Диагноз'
                        />
                    </Item>
                    <Item picker>
                        <Input
                            onChange={handleChange.bind(this, 'description')}
                            value={values.description}
                            multiline
                            clearButtonMode='while-editing'
                            placeholder='Подробное описание или заметка'
                            style={{ paddingTop: 15, paddingBottom: 15 }}
                        />
                    </Item>
                    <Item picker>
                        <Input
                            onChange={handleChange.bind(this, 'price')}
                            value={values.price}
                            keyboardType='number-pad'
                            clearButtonMode='while-editing'
                            placeholder='* Цена'
                        />
                    </Item>

                    <ButtonRN onPress={showDatepicker}>
                        <Text style={{ fontSize: 18, fontWeight: '400' }}>
                            Дата: {formatDate(date)}, время: {date.toTimeString().split(' ')[0].slice(0, 5)}
                        </Text>
                    </ButtonRN>

                    {show && (
                        <DateTimePicker
                            timeZoneOffsetInSeconds={21600}
                            minimumDate={new Date()}
                            value={date}
                            mode={mode}
                            is24Hour={true}
                            display='default'
                            locale='ru-RU'
                            minuteInterval={10}
                            onChange={onChange}
                        />
                    )}

                    <ButtonView>
                        <Button
                            onPress={submitHandler}
                            rounded
                            block
                            iconLeft
                            style={{ backgroundColor: '#84D269' }}
                        >
                            <Icon type='Entypo' name='plus' style={{ color: '#fff' }} />
                            <Text style={{ color: '#fff' }}>Добавить прием</Text>
                        </Button>
                    </ButtonView>
                    <Label style={{ marginTop: 10, fontSize: 16 }}>
                        Поля помеченные звездочкой <TomatoText>*</TomatoText> обязательны для заполнения
                    </Label>
                </Form>
            </Content>
        </Container>
    )
}

const ButtonRN = styled.TouchableOpacity({
    paddingTop: 15,
    paddingLeft: 5,
})

const ButtonView = styled.View({
    marginTop: 15,
})

const TomatoText = styled.Text({
    color: 'tomato',
})

export default AddAppointmentScreen

3 个答案:

答案 0 :(得分:0)

我还没有遍历您的代码,但是我可以告诉您如何按照标题将参数传递到下一个屏幕。

  toNavigate = (user) => {

    this.setState({ isLoading: false },
        () => { this.props.navigation.push('Main', { userData: user }) })
//I am sending user into userData to my Main screen
}

我收到的像是

render(){
 user = this.props.route.params.userData;
 }

如果有任何问题让我知道。

希望有帮助!

答案 1 :(得分:0)

这可以在导航容器内部时使用useNavigation挂钩完成。

import { NavigationContainer, useNavigation } from '@react-navigation/native';
const HeaderRight = ({ navigation, target }) => {
  const navigation = useNavigation();
    return (
        <Button transparent onPress={() => navigation.navigate(target)}>
            <Icon name='plus' type='Entypo' style={{ fontSize: 26 }} />
        </Button>
    )
}

而且您必须像下面那样传递目标,因为无法从那里访问导航,无论如何传递没有意义。

headerRight: () => <HeaderRight target={'Profile'} />,

希望这会有所帮助。

答案 2 :(得分:0)

我这样解决了:

  1. 在StackScreen中获取参数-您需要传递至路线和导航选项,然后才能获得如下所示的路线参数:
   name1  name2    name3  nameXXX
0  1.020  0.120  0.47300   46.872
1  0.644  0.134  0.64500   44.772
2  0.860  0.132  0.52890  109.872
3  1.040  0.110  0.66349   46.872
  1. 然后我在HeaderRight组件中获取PatientId并将其传递到新屏幕,并使用具有导航功能的第二个参数,如下所示(当然,可以选择不使用该组件并将其从Stack.Screen传递给我,但我将其传递给了我自己目的):
    <Stack.Screen
        name='Patient'
        component={PatientScreen}
        options={({ route, navigation }) => {
            return {
                title: 'Карта пациента',
                headerTintColor: '#2A86FF',
                headerTitleAlign: 'center',
                headerTitleStyle: {
                    fontWeight: 'bold',
                    fontSize: 20,
                },
                headerBackTitleVisible: false,
                headerRight: () => (
                    <HeaderRight target={'AddAppointment'} patientId={route.params.patientId} />
                ),
            }
        }}
    />
  1. 在第三个屏幕中,我得到如下的PatientId:

const HeaderRight = ({ patientId, target }) => { const navigation = useNavigation() return ( <Button transparent onPress={() => navigation.navigate(target, { patientId })}> <Icon name='plus' type='Entypo' style={{ fontSize: 26 }} /> </Button> ) }