使用钩子和标头功能进行反应导航-状态未更新

时间:2019-07-22 03:51:11

标签: reactjs react-navigation

尝试使用带有挂钩和导航标题中的按钮的反应导航。

我可以将handleShowModalLogin函数传递给导航标题,并且可以看到单击了按钮,但是问题是setShowLoginModal没有将showLoginModal状态更新为true。不知道为什么这不起作用。

import React, { useState, useEffect, useLayoutEffect } from "react";
import {
  Image,
  Platform,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
  Button,
} from 'react-native';

import LoginModal from './users/LoginModal';

const HomeScreen = ({navigation}, props) => {

  const [showLoginModal, setShowLoginModal] = useState(false);

  const handleShowModalLogin = (value) => {
    console.log("showLoginModal button clicked: ", value)
    if(value === "on"){
      setShowLoginModal(true);
    }else{
      setShowLoginModal(false);
    }
  }

  useEffect(() => {
    console.log('navigation handler set with showLoginModal set:', showLoginModal)
    navigation.setParams({ handleShowModalLogin: handleShowModalLogin });
  }, []);

  useEffect(() => {
    console.log("showLoginModal value changed: ", showLoginModal), [showLoginModal]
  })

  return (
    <View style={styles.container}>

      <LoginModal showLoginModal={showLoginModal} />

      <ScrollView
        style={styles.container}
        contentContainerStyle={styles.contentContainer}>

      </ScrollView>

    </View>
  );

};

HomeScreen.navigationOptions = ({ navigation }) => ({
  title: "Home",
  headerRight: (
    <View style={styles.headerComContainer}>
      <Button
        onPress={() => {
          navigation.getParam('handleShowModalLogin')('on')
        }}
        title="Login"
        color="#841584"
        accessibilityLabel="Login" />
    </View>
  )
});

这是登录模式组件。

import React, { useState } from "react";
import { Text, TouchableOpacity, View, ScrollView } from "react-native";
import Modal from 'modal-enhanced-react-native-web';

export default function LoginModal(props){

  const [visibleModal, setModalVisible] = useState(props.showLoginModal);

  return (
    <View>

      <Modal
        isVisible={visibleModal}
        onBackdropPress={() => setModalVisible(false)}
      >
        <View>
          <Text>Hello!</Text>
          <TouchableOpacity onPress={() => setModalVisible(false)}>
            <View>
              <Text>Close</Text>
            </View>
          </TouchableOpacity>
        </View>
      </Modal>

    </View>
  );

}

1 个答案:

答案 0 :(得分:0)

const [visibleModal, setModalVisible] = useState(props.showLoginModal);

LoginModal中的此代码创建一个状态,其初始 initial 值为props.showLoginModal。但是,在该初始值之后,该道具就没有任何关联。稍后更改道具不会导致状态更改。

您似乎正在尝试混合使用LoginModal作为受控组件(父组件处理逻辑,然后通过props控制逻辑)和非受控组件(组件管理自己的状态)。相反,我建议选择一个。

从您试图在外部对其进行控制的事实来看,您似乎想创建一个受控组件。因此,您的登录模式将需要修改,以具有其他道具来将点击通知父母。也许是“ onBackdropPressed”和“ onClosePressed”,如:

export default function LoginModal(props){
  return (
    <View>
      <Modal
        isVisible={props.showLoginModal}
        onBackdropPress={() => props.onBackdropPressed()}
      >
        <View>
          <Text>Hello!</Text>
          <TouchableOpacity onPress={() => props.onClosePressed()>
            <View>
              <Text>Close</Text>
            </View>
          </TouchableOpacity>
        </View>
      </Modal>
    </View>
  );
}

别忘了修改主屏幕以将其他道具传递进去,如:

<LoginModal 
  showLoginModal={showLoginModal} 
  onBackdropPressed={() => setShowLoginModal(false)}
  onClosePressed={() => setShowLoginModal(false)}
/>