即使我只更新嵌套属性,Redux 商店也会更新所有内容?

Redux store updates everything even if I just update a nested attribute?

在我的应用程序中,用户应该可以编辑他的名字。我想过把他的初始名字作为默认值 useState()。这非常有效 - 名称也已更新。

function EditName(props) {
    const { navigation, dispatch, initFirstName } = props;

    const [text, setText] = useState(initFirstName);

    return (
      <>
        <Button title="Save" onPress={() => dispatch(updateFirstName(text))} />
        <TextInput
          style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
          onChangeText={(inp) => setText(inp)}
          value={text}
        />
      </>

    )


}

function mapStateToProps(state) {
  return (
    {
      initFirstName: state.user.data.firstName,
    }
  );
}

export default connect(mapStateToProps)(EditName);

但现在我遇到了一个问题,如果用户单击保存按钮并处理 dispatch(updateFirstName(text))text 再次被 initFirstName 覆盖。

我的 Redux(工具包)存储结构如下:

{
  data: {
    firstName: "Test"
  },
  updateFirstName: {
   pending: null,
   error: null,
  },    
}

updateFirstName(text) 方法调度设置 state.updateFirstName.pending = true; 的操作。如果我忽略它 - 一切正常。

所以我猜想创建了一个对商店(状态)的新引用并且 React 认为:“哦 - 我有一个新的 initFirstName”(除此之外它仍然是一样的,因为更新还没有发生)。

执行此操作的更好方法是什么?这个问题有什么解决方案?

也许尝试创建一个将被调用的函数,而不是分配 onPress 箭头函数。基本上,该函数将以 text.

的初始值调用

确保使用 text 的当前值,试试这个:

const saveHandler = () => {
    dispatch(updateFirstName(text))
}
...
<Button title="Save" onPress={saveHandler} />

@Taghi Khavari 猜对了:它与我在 Whosebug 上发布的代码无关 - 这是一个 React Navigation 问题。

我在我的应用程序中使用 nested navigators。我在我的 App 函数中声明了嵌套导航器,这导致 EditName 组件在状态更改后多次重新安装(虽然我实际上不知道为什么)。

当我在我的 App 函数外声明嵌套导航器时(如下例所示),它起作用了,组件只安装了一次。谁能解释一下为什么?

function Home() {
  return (
    <NestedStack.Navigator>
      <NestedStack.Screen name="Profile" component={Profile} />
      <NestedStack.Screen name="Settings" component={Settings} />
    </NestedStack.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <RootStack.Navigator mode="modal">
        <RootStack.Screen
          name="Home"
          component={Home}
          options={{ headerShown: false }}
        />
        <RootStack.Screen name="EditPost" component={EditPost} />
      </RootStack.Navigator>
    </NavigationContainer>
  );
}