React Native:使用上下文将子状态挂钩到父状态 [英] React Native: Hook Child State to Parent's State using Context
问题描述
我正在尝试在 ChildScreen 中重新渲染 {userNumbers}
.我设法在 Home 中添加了 userNumbers
状态,但它没有重新渲染文本.
I'm trying to rerender {userNumbers}
in ChildScreen. I managed to add userNumbers
state in Home, but it doesn't rerender the text.
UserContext.js
import { createContext } from 'react';
export const UserContext = createContext(null);
Home.js
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { UserContext } from "../contexts/UserContext";
import ChildScreen from "ChildScreen";
const Stack = createStackNavigator();
export default function Home() {
const [state, dispatch] = React.useReducer((prevState, action) => {
switch (action.type) {
case 'ADD_USER':
return {
...prevState,
users: state.users + action.newUsers
};
}
}, {
users: 0
});
const userContext = React.useMemo(
() => ({
addUsers: async data => {
dispatch({
type: 'ADD_USER',
newUsers: data.newUsers
});
},
userNumbers: state.users
}),
[]
);
return (
<UserContext.Provider value={userContext}>
<Stack.Navigator>
<Stack.Screen name="ChildScreen" component={ChildScreen} />
</Stack.Navigator>
</UserContext>
)
}
ChildScreen.js
import React from 'react';
import { View, Text } from 'react-native';
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
import { UserContext } from "../contexts/UserContext";
export default function ChildScreen() {
const { addUsers, userNumbers } = React.useContext(UserContext);
render (
<View><Text>{userNumbers}</Text></View>
<TouchableWithoutFeedback onPress={() => { addUsers({newUsers: 999)}) }>
<Text>Add 999 Users</Text>
</TouchableWithoutFeedback>
)
}
推荐答案
state.users
改变时需要重新创建userContext value
,添加state.users
作为 useMemo 的依赖项,否则您的上下文值将保持相同的值引用,并会注意到任何侦听器的触发变化
You need to re-create the userContext value
when state.users
change by adding state.users
as a dependency to useMemo otherwise you context value will keep holding the same reference of value and will note trigger change for any listeners
const userContext = React.useMemo(
() => ({
addUsers: data => {
dispatch({
type: 'ADD_USER',
newUsers: data.newUsers
});
},
userNumbers: state.users
}),
[state.users] // Add a dependency here so that user update changes reference
);
你也应该将你的reducer定义为纯的,即它不应该使用来自闭包的状态
Also you should define your reducer to be pure, i.e it shouldn't use state from closure
const [state, dispatch] = React.useReducer((prevState, action) => {
switch (action.type) {
case 'ADD_USER':
return {
...prevState,
users: prevState.users + action.newUsers // use prevState here
};
}
}, {
users: 0
});
附言您不需要将 addUsers
函数定义为 async
.dispatch
异步发生,但需要重新渲染才能生效,您无需等待
P.S. You need not define addUsers
function to be async
. dispatch
happens asynchronously but requires a re-render to take effect and you need not wait on it
这篇关于React Native:使用上下文将子状态挂钩到父状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!