I have a typescript react-native application. I have used navigation with some sucess but in this case, no matter what I do, the id, filename, and file are all undefined.
Here is the code with the issue. I know according to react-native navigation doing what I'm doing with the file isn't necessary great coding practice, but this is just displaying a file, so it's not a huge deal. (I am storing the filename and id in a sqlite database). I added the useState hoping that the file gets passed or change that it can change the state.
export type Props = {
navigation: PropTypes.func.isRequired;
id:PropTypes.int.isRequired;
filename:Protypes.string.isRequired;
file:{
name: PropTypes.string.isRequired;
uri: PropTypes.path.isRequired;
type: PropTypes.mime.isRequired};
};
const FileViewScreen: React.FC<Props> = ({navigation,id,filename,file}) => {
console.log("File View Screen?")
console.log("currentFile");
console.log(id)
console.log(currentFile)
console.log(filename)
console.log(file)
const [currentFile,setCurrentFile] = useState(file);
Here is where the user gets routed to the FileScreen. Here I was testing to see if any id is passed, I'm aware that the id needs changed to the id and not 1 but this was testing.
const HomeScreen: React.FC<Props> = ({navigation}) => {
const [loading, setLoading] = useState(false);
const [file, setFile] = useState({});
const [files, setFiles] = useState([]);
const downloadFile = async () => {
try {
...
const newEntry = {
name: 'ImageFileName' + Math.random().toString(),
uri: result.path,
type: result.mime,
};
const res = await addFile(result.path);
console.log(res)
navigation.navigate('FileView', { id:1,filename:res,file:newEntry });
} catch (error) {
console.log('downloadFile error', error);
}
};
return (
<View style={styles}>
<Text>Welcome Home</Text>
{loading && <ActivityIndicator size={'large'} color="#000" />}
{!loading && (
<>
<Button
title="Start Recording"
onPress={downloadFile}
/>
Here is the addFile function. I don't think this matters but I've been wrong before. Here
export const addFile = file_path => {
db.transaction(txn => {
console.log("db transaction")
console.log(file_path)
const response = txn.executeSql(
'INSERT INTO files(file_path,uploaded) VALUES (' +
file_path +
',' +
false +
')',
(sqlTxn, res) => {
console.log("adding")
console.log(`${file_path} video added successfully`);
return file_path;
},
error => {
console.log('error on adding file ' + error.message);
return 0;
},
);
});
console.log(resopnse)
};
In my app.js (i do have a working register and, login, home screen. Right now this is the only time I have an issue.
<NavigationContainer>
<Stack.Navigator initialRouteName={initalRoute}>
<Stack.Screen name="Login">
{props => (
<LoginScreen {...props} setToken={setUserToken} setUser={setUser} />
)}
</Stack.Screen>
<Stack.Screen name="Home">
{props => (
<HomeScreen {...props}/>
)}
</Stack.Screen>
<Stack.Screen name="Register" component={RegisterScreen} />
<Stack.Screen name="FileView">
{props =>(
<FileViewScreen {...props} />
)}
</Stack.Screen>
</NavigationContainer>
Things that I've tried.
Things that I haven't tried
If your FileViewScreen
is a child component of some parent view then id,filename,file
will be available from component props
object. If instead you navigate to FileViewScreen
from another screen then id,filename,file
will be part of route
prop.
To account for both use cases you could so something like this
const FileViewScreen: React.FC<Props> = (props) {
// try extracting props from root prop object
let { id,filename,file } = props;
// if navigation route params are available,
// then extract props from route.params instead
// you could also check if id, filename, file etc are null
// before extracting from route.params
const { route } = props;
if (route && route.params) {
({ id,filename,file } = route.params);
}
...
}