React Native:使用上下文将子状态挂钩到父状态 [英] React Native: Hook Child State to Parent's State using Context

查看:57
本文介绍了React Native:使用上下文将子状态挂钩到父状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆