【发布时间】:2021-03-19 16:52:47
【问题描述】:
我有一个包含一些导出函数的帮助文件。 我有一个包含一些共享数据的 ContextProvider。 现在我需要从辅助函数内部更改上下文中的数据。
但是,如果我在函数体内部调用 useContext 语句以及在外部调用,都会出现错误。
如果我在帮助文件中创建一个默认函数 MyHelper(),我可以在里面调用 useContext 并使其工作。 但是我不能将不同的函数用作另一个文件中的 api。只有 MyHelper()。
如何在另一个 .js 文件中调用多个导出函数并更改那里的上下文数据?
我制作了一个示例代码,它显示了我的问题,而没有原始代码的开销:
MyScreen.js
import React, {useContext} from 'react';
import {View, Button} from 'react-native';
import {MyContext} from '../MyProvider'; // assume this exists and is working
import {myChangeNameFunction} from '../helpers/MyHelper';
const MyScreen = () => {
const {name, setName} = useContext(MyContext); // does work here
return (
<View>
<Button
title={name} //just as easy example
onPress={() => myChangeNameFunction('test')}
/>
</View>
);
}
export default MyScreen;
MyHelper.js
import React, {useContext} from 'react';
import {MyContext} from '../MyProvider';
//const {name, setName} = useContext(MyContext); // does not work
export const myChangeNameFunction = (test) => {
//const {name, setName} = useContext(MyContext); // does not work
setName(test);
}
export const anotherFunction = (test) => {
//const {name, setName} = useContext(MyContext); // does not work
setName(test);
}
更新:
也许是一个更好的例子:
MyScreen.js
import React, {useContext} from 'react';
import {View, Text, Button} from 'react-native';
import GeocoderOsm from 'react-native-geocoder-osm';
import {MyContext} from '../MyProvider';
//import {getGPSbyAddress} from '../helpers/MyHelper';
// I want to exclude functions below and instead import them from helper file
const MyScreen = () => {
const {address, setAddress} = useContext(MyContext);
// imagine here are a lot of functions like these below.
// I want to exclude them from this file to a MyHelper.js
// So the MyScreen.js File is not so big and with chaos.
// Also I could import and reuse these functions from other Screens than MyScreen.js.
const getGPSbyAddress = (place) => {
GeocoderOsm.getGeoAddress(place).then((res) => {
// setAddress is working here. But if I outsource the function to MyHelper.js File
// I can't access the setAddress in the Context. And I also can't return
// the res output because its kind of async - because of the then() function
// of the OSM lib. So I just want to save it to context if its finished.
setAddress(res);
}).catch((e) => {
console.log('error', e)
});
}
return (
<View>
<Button
title='Get GPS'
onPress={() => getGPSbyAddress('London') }
/>
<Text>{address}</Text>
</View>
);
}
export default MyScreen;
MyHelper.js
import React, {useContext} from 'react';
import GeocoderOsm from 'react-native-geocoder-osm';
import {MyContext} from '../MyProvider';
//const {address, setAddress} = useContext(MyContext); // does not work here
export const getGPSbyAddress = (place) => {
//const {address, setAddress} = useContext(MyContext); // does not work here
GeocoderOsm.getGeoAddress(place).then((res) => {
setAddress(res); // this is not working here because I cant call useContext anywhere.
}).catch((e) => {
console.log('error', e)
});
}
export const getAddressByGPS = (lat, lon) => {
//const {address, setAddress} = useContext(MyContext); // does not work here
GeocoderOsm.getGeoCodePosition(lat, lon).then((res) => {
setAddress(res); // this is not working here because I cant call useContext anywhere.
}).catch((e) => {
console.log('error', e)
});
}
// ... a lot of more functions
因此,如果没有解决方案从 MyHelper.js 文件中的函数设置上下文...然后我如何将一些函数外包到一个单独的文件中(以便更好地阅读和重用)并获得我的 {address}使用从可能异步获取地址的外包函数获取的数据呈现。感谢您的耐心等待。
【问题讨论】:
-
错误是什么?
-
如果我在函数内部调用 useContext:“错误:无效的钩子调用。只能在函数组件的主体内部调用钩子。”如果我在它之外调用 useContext 。如果我只创建一个 MyHelper 函数并在其中使用它,错误会显示“未定义”,因为上下文挂钩超出了被调用函数的范围。
-
添加
MyHelper.js的所有代码。 -
useContext是一个反应钩子。它需要在反应组件内部调用。但是,您可以使用内置钩子编写自己的自定义钩子(一个函数)。但是这个钩子仍然需要在组件内部调用。自定义钩子的命名约定应该以use开头,以便钩子 linter 插件正常工作。 -
@yudhiesh 就是这样。
标签: reactjs react-native react-hooks