在 React Native 中使用 Context 和 React Navigation 处理嵌套屏幕上的更新

Posted

技术标签:

【中文标题】在 React Native 中使用 Context 和 React Navigation 处理嵌套屏幕上的更新【英文标题】:Handling updates on nested screens using Context and React Navigation in React Native 【发布时间】:2021-08-27 21:52:30 【问题描述】:

假设我正在构建一个购物清单应用。我有能力创建不同的购物清单。我有三个屏幕:

-- Shopping Lists: displays all the lists
---- List Details: displays all the items from a list
------ List Item Details: displays all the info about an item

为了存储状态并避免道具钻孔,我使用了 Context。我的状态可能如下所示:

shoppingLists = [

  title: 'Groceries',
  items: [
    name: 'Apples',
    quantity: 3
    ... (other info)
  ,
  items: [
    name: 'Oranges',
    quantity: 6,
    ...
  ]
,

  title: 'Office Supplies',
  items: [
    name: 'Paper',
    quantity: 2
    ... (other info)
  ,
  items: [
    name: 'Pens',
    quantity: 25,
    ...
  ]
]

当我点击购物清单屏幕上的购物清单时,我会这样做

navigation.navigate('ListDetails', params: listItem)

在“列表详细信息”屏幕中,我可以更改项目的数量或删除它们。如果我执行任何这些操作,我必须对我的服务器进行 API 调用以更新数据库上的值。以下是我的问题:

    目前我将值存储在屏幕中的局部变量中,例如:
const [title, setTitle] = useState(props.route.params.title)
const [items, setItems] = useState(prop.route.params.items)

如果我更改数量,我会使用 setState 更新我的本地数组,然后调用 API 来更新上下文。当添加更多嵌套屏幕时,这会导致问题。 例如,如果我让用户能够在 List Item Details 屏幕中更改项目数量,那么当用户返回 List Details 屏幕时,这些值将不会更新。

我的问题是,获取上下文状态并在本地更新它的正确方法是什么? 例如,我应该这样做:

navigation.navigate('ListDetails', params:  listName: 'Groceries' )

然后在我的列表详细信息屏幕中从数组中获取正确的列表,例如:

const lists = useContext(ShoppingLists)
const list = lists.filter(l => l.title === props.route.params.title)

正确的方法是什么?

    我的另一个问题是一个更普遍的问题。我想使用乐观的响应:当用户更新列表中项目的数量时,我在本地更新它并将请求发送到服务器。如果有错误回滚更改。哪种方法是正确的?

谢谢!

【问题讨论】:

【参考方案1】:

    我建议不要以这种方式更新上下文数据。您可以改为在上下文中创建 setList() 方法,或 updateList() 将新数据聚合到现有数据。

    这与上一个有关。您可以将 POST 到服务器的逻辑包装在 try-catch 块中,并在不成功时抛出错误。然后,您只有在成功时才能设置新值。另一种选择是返回承诺,这样您就可以处理来自外部的错误,例如setList().then(response => ).catch(error => ),尽管我认为这看起来不太好。

【讨论】:

【参考方案2】:

认为您过于复杂了,而且在您的列表中,您没有为每个项目显示id。您应该使用所有项目及其唯一的id 构建您的数据库,然后在需要时调用它。 id 永远不应更改,并且更容易传递和引用。

例如,您可以仅使用 idquantity 在上下文中构建对象,并为此使用 useReducer

https://reactjs.org/docs/hooks-reference.html#usereducer

【讨论】:

以上是关于在 React Native 中使用 Context 和 React Navigation 处理嵌套屏幕上的更新的主要内容,如果未能解决你的问题,请参考以下文章

尝试在 create-react-native-app 项目 (expo) 中使用 react-native-fs

React-native:如何在 React-native 中使用(和翻译)带有 jsx 的 typescript .tsx 文件?

如何在 React Native 中使用 React Native Video 显示多个视频? [关闭]

如何在React Native中使用CreateBottomTabNavigator?

使用 react-native router-flux 时,BackHandler 在 react-native 侧面菜单中不起作用

无法使用 react-native-svg 或 Svg/expo 让 Svg 显示在 react-native 中