在父 Refresh React Native 上更新子组件数据
Update Child Component Data on Parent Refresh React Native
我是 React Native 的新手,目前正在尝试在我的应用程序中实现下拉刷新功能。这是我的 Parent
组件片段:
function MainScreenBoss({ navigation }) {
const [refreshing, setRefreshing] = useState(false);
//here I'm trying to refresh (example from docs)
const onRefresh = React.useCallback(async () => {
setRefreshing(true);
wait(2000).then(setRefreshing(false));
}, [refreshing]);
return (
<ScrollView
contentContainerStyle={styles.containerScroll}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}>
<View style={styles.container}>
//other components here
<View style={styles.containerWidget}>
//need to refresh this component
<Widget style={styles.widget} />
</View>
</View>
</ScrollView>
);
}
我正在尝试刷新 Widget 组件,因为它在其中调用了 API url 并带有加载动画。这是 Widget
组件的片段:
function Widget() {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
//call to api returns data
useEffect(() => {
getData(API_GET_WIDGET_DATA, setLoading, setData);
}, []);
return (
<View style={styles.container}>
{isLoading ? (
<ActivityIndicator
loader="blue"
visible={isLoading}
style={styles.animation}
/>
) : (
<>
<View style={styles.Contents}>
//need to refresh data is it used in here when loading is finished
</View>
</>
)}
</View>
);
}
我想我需要强制更新widget组件或以某种方式重新启动加载功能,但我不太明白我该怎么办。
编辑:
api 函数如下所示:
export function getData(reqOptions, setLoading, setData) {
fetch(apiURL, reqOptions)
.then((response) => response.json())
.then((json) => setData(json.data))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}
如果我理解得很好,为了更新您的小部件,您必须重新执行 useEffect
中的提取。
您当前的 useEffect
仅在组件挂载时执行,作为 dep。数组为空。从您的父组件的外观来看,Widget 不会被卸载,因此您的 useEffect
只被调用一次。
您需要做的是获取您的 refreshing
状态并将其传递给 Widget,以便它知道何时必须重新获取数据。
尝试这样的事情:
function MainScreenBoss({ navigation }) {
const [refreshing, setRefreshing] = useState(false);
//here I'm trying to refresh (example from docs)
const onRefresh = React.useCallback(async () => {
setRefreshing(true);
wait(2000).then(setRefreshing(false));
}, [refreshing]);
return (
<ScrollView
contentContainerStyle={styles.containerScroll}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}>
<View style={styles.container}>
//other components here
<View style={styles.containerWidget}>
//need to refresh this component
<Widget style={styles.widget} refreshing={refreshing} /> // pass this prop
</View>
</View>
</ScrollView>
);
}
小部件:
function Widget(props) {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
//call to api returns data
useEffect(() => {
getData(API_GET_WIDGET_DATA, setLoading, setData);
}, []);
useEffect(() => {
if (props.refreshing) {
getData(API_GET_WIDGET_DATA, setLoading, setData);
}
}, [props.refreshing]); // on every refreshing `true` state
return (
<View style={styles.container}>
{isLoading ? (
<ActivityIndicator
loader="blue"
visible={isLoading}
style={styles.animation}
/>
) : (
<>
<View style={styles.Contents}>
//need to refresh data is it used in here when loading is finished
</View>
</>
)}
</View>
);
}
编辑:
您可以修改现有的 useEffect
以包括 data
的检查,或者创建另一个仅在挂载时运行,另一个 useEffect
运行 在更新状态上运行。我添加了第二种情况。
编辑 2:
这没什么不对,实际上这样更好,因为刷新是在正确的时间处理的,当调用完成并且数据完成时。使用您当前的配置,调用可能未完成,但在 2 秒后您将刷新设置为 false,这可能会带来问题。
hooks 的美妙之处在于,与 hooks 引入之前 React 的 class 方法相比,你可以使用任意数量的 hooks。所以这没有问题,但你实际上可以改变它并得到类似的东西:
useEffect(() => {
if (!data || props.refreshing) {
getData(API_GET_WIDGET_DATA, setLoading, setData);
}
}, [data, props.refreshing]);
如果可以的话,最后一件事:我不会将状态设置器传递给你的 fetch fn,我会处理组件中的状态更新并确保 fn returns你的数据。这只是为了关注点分离的原因。
我是 React Native 的新手,目前正在尝试在我的应用程序中实现下拉刷新功能。这是我的 Parent
组件片段:
function MainScreenBoss({ navigation }) {
const [refreshing, setRefreshing] = useState(false);
//here I'm trying to refresh (example from docs)
const onRefresh = React.useCallback(async () => {
setRefreshing(true);
wait(2000).then(setRefreshing(false));
}, [refreshing]);
return (
<ScrollView
contentContainerStyle={styles.containerScroll}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}>
<View style={styles.container}>
//other components here
<View style={styles.containerWidget}>
//need to refresh this component
<Widget style={styles.widget} />
</View>
</View>
</ScrollView>
);
}
我正在尝试刷新 Widget 组件,因为它在其中调用了 API url 并带有加载动画。这是 Widget
组件的片段:
function Widget() {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
//call to api returns data
useEffect(() => {
getData(API_GET_WIDGET_DATA, setLoading, setData);
}, []);
return (
<View style={styles.container}>
{isLoading ? (
<ActivityIndicator
loader="blue"
visible={isLoading}
style={styles.animation}
/>
) : (
<>
<View style={styles.Contents}>
//need to refresh data is it used in here when loading is finished
</View>
</>
)}
</View>
);
}
我想我需要强制更新widget组件或以某种方式重新启动加载功能,但我不太明白我该怎么办。
编辑: api 函数如下所示:
export function getData(reqOptions, setLoading, setData) {
fetch(apiURL, reqOptions)
.then((response) => response.json())
.then((json) => setData(json.data))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}
如果我理解得很好,为了更新您的小部件,您必须重新执行 useEffect
中的提取。
您当前的 useEffect
仅在组件挂载时执行,作为 dep。数组为空。从您的父组件的外观来看,Widget 不会被卸载,因此您的 useEffect
只被调用一次。
您需要做的是获取您的 refreshing
状态并将其传递给 Widget,以便它知道何时必须重新获取数据。
尝试这样的事情:
function MainScreenBoss({ navigation }) {
const [refreshing, setRefreshing] = useState(false);
//here I'm trying to refresh (example from docs)
const onRefresh = React.useCallback(async () => {
setRefreshing(true);
wait(2000).then(setRefreshing(false));
}, [refreshing]);
return (
<ScrollView
contentContainerStyle={styles.containerScroll}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}>
<View style={styles.container}>
//other components here
<View style={styles.containerWidget}>
//need to refresh this component
<Widget style={styles.widget} refreshing={refreshing} /> // pass this prop
</View>
</View>
</ScrollView>
);
}
小部件:
function Widget(props) {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
//call to api returns data
useEffect(() => {
getData(API_GET_WIDGET_DATA, setLoading, setData);
}, []);
useEffect(() => {
if (props.refreshing) {
getData(API_GET_WIDGET_DATA, setLoading, setData);
}
}, [props.refreshing]); // on every refreshing `true` state
return (
<View style={styles.container}>
{isLoading ? (
<ActivityIndicator
loader="blue"
visible={isLoading}
style={styles.animation}
/>
) : (
<>
<View style={styles.Contents}>
//need to refresh data is it used in here when loading is finished
</View>
</>
)}
</View>
);
}
编辑:
您可以修改现有的 useEffect
以包括 data
的检查,或者创建另一个仅在挂载时运行,另一个 useEffect
运行 在更新状态上运行。我添加了第二种情况。
编辑 2:
这没什么不对,实际上这样更好,因为刷新是在正确的时间处理的,当调用完成并且数据完成时。使用您当前的配置,调用可能未完成,但在 2 秒后您将刷新设置为 false,这可能会带来问题。
hooks 的美妙之处在于,与 hooks 引入之前 React 的 class 方法相比,你可以使用任意数量的 hooks。所以这没有问题,但你实际上可以改变它并得到类似的东西:
useEffect(() => { if (!data || props.refreshing) { getData(API_GET_WIDGET_DATA, setLoading, setData); } }, [data, props.refreshing]);
如果可以的话,最后一件事:我不会将状态设置器传递给你的 fetch fn,我会处理组件中的状态更新并确保 fn returns你的数据。这只是为了关注点分离的原因。