反应本地redux状态更新,但不渲染组件

我有两个名为A和B的组件,在BI中有一个要在组件A中选择和更新的语言的列表。当我从列表中更改语言时,我正在使用Redux进行状态管理。已更新(使用redux-logger获取日志)。但是问题是当我使用react-navigation返回组件A时,更新后的状态值未更新,我只能看到状态的旧值

ScreenA.js

class ScreenA extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      selectedLanguage: this.props.state.defaultLangName
    }
  }

  render(
       return (
            <Container>
            <Content  style={{  backgroundColor: item.backgroundColor }}>
              <View style={styles.logoContainer}>
              <Text>test page</Text>
              </View>

            <View style={styles.cardParent}>
              <View style={styles.card}>
              <Item style={styles.listItem}>
                <Button transparent style={styles.contentChecked} onPress={() => this._openLang()}>
                  <Text style={styles.listbtn}>{this.state.selectedLanguage}</Text>
                  <Icon name='ios-arrow-forward' style={styles.iconChecked}/>
                </Button>   
              </Item>
              </View>
              </View>
            </Content>
        </Container>
          );
  )

}

export default connect(
    state => ({ state : state.introauthenticate }),dispatch => ({
        actions: bindactionCreators(introactions,dispatch)
    })
  )(ScreenA);

ScreenB.js

class ScreenB extends Component {

    constructor(props){
      super(props);
      this.state = {
              langChecked: '0'
          };
    }


    flatListItemSeparator = () => {
        return (
          <View
            style={{
              height: 1,width: "100%",backgroundColor: "#999",}}
          />
        );
    }

    _selectLanguage (val,name){
      this.setState({ langChecked: val });
      this.props.actions.changeLanguage(val,name,this.props.navigation.navigate);
      //this.props.navigation.navigate('Intro');
    }

    renderItem = (item )=> {
      return(
        <TouchableHighlight
            style={styles.boxSelect}
            underlayColor="transparent"
            onPress={() => this._selectLanguage(item.Value,item.Name)}
        >
            <View style={styles.contentChecked}>
              <Text style={styles.item}  > {item.Name} </Text>
              {this.state.langChecked === item.Value && <Icon name="ios-checkmark-circle" style={styles.iconChecked}/>}
            </View>
         </TouchableHighlight>
      )
    }

    render() {
      return (
          <Container>
          <Header>
            <Left>
              <Button transparent onPress={() => this.props.navigation.goBack()}>
                <Icon name='ios-arrow-back' />
              </Button>
            </Left>
            <Body>
              <Title>Languages</Title>
            </Body>
            <Right />
          </Header>        
        <Content>
        <flatList
         data={ langs }
         keyExtractor={(item) => item.Value}
         ItemSeparatorComponent = {this.flatListItemSeparator}
         renderItem={({item}) => this.renderItem(item)}
        />
        </Content>
      </Container>
      );
    }
  }

  export default connect(
    state => ({ state: state.introauthenticate }),dispatch)
    })
  )(ScreenB);

reducer.js

export const CHANGE_LANGUAGE = "CHANGE_LANGUAGE";

export function changeLanguage(langValue,langName,navigateTo) { // Fake authentication function
  return async dispatch => {
      try {
          if (langValue && langName) { //If the email and password matches
              const session = { langValue : langValue,langName:langName } // Create a fake token for authentication

              setTimeout(() => { // Add a delay for faking a asynchronous request
                  dispatch(setLanguage(session)) // Dispatch a successful sign in after 1.5 seconds
                  navigateTo('Intro') // If successfull login navigate to the authenticated screen
              },1500)
          }  
      } catch (err) { // When something goes wrong
          console.log(err)

      }
  };
} 


function setLanguage(lang){
  return {
      type: types.CHANGE_LANGUAGE,data: {
          lang: lang
      }
  };
}

const initialsliderState = {
    defaultLang:'en',defaultLangName:'English',};

  export default function introauthenticate(state = initialsliderState,action = {}) {

    switch (action.type) {
        case types.CHANGE_LANGUAGE: 
        return { 
          ...state,defaultLang: action.data.lang.langValue,defaultLangName: action.data.lang.langName,};
      default:
        return state;
    }
  }

记录器:

LOG  %c prev state  "introauthenticate": {"defaultLang": "nl","defaultLangName": "Deutsch","isAuthSlider": false,"requestingsliderRestore": false}
LOG  %c action      {"data": {"lang": {"langName": "English","langValue": "en"}},"type": "CHANGE_LANGUAGE"}
LOG  %c next state "introauthenticate": {"defaultLang": "en","defaultLangName": "English","requestingsliderRestore": false}}
qq393901347 回答:反应本地redux状态更新,但不渲染组件

您正在使用作为prop传递的值来初始化ScreenA的状态,请不要对其进行更新。当您使用Redux存储当前语言时,ScreenA中不需要任何状态。连接组件时,会将其来自商店的相关数据作为道具传递。似乎您正在尝试通过以state的形式传递状态来“覆盖”状态,但这并不会像在this.props.state中那样在this.state中那样更新状态。您需要做的只是将语言作为道具传递给ScreenA

export default connect(
    state => ({ selectedLanguage : state.introauthenticate.defaultLang }),dispatch => ({
        actions: bindActionCreators(introActions,dispatch)
    })
)(ScreenA);

,然后从道具中读取所选语言:

<Text style={styles.listbtn}>{this.props.selectedLanguage}</Text>

更新商店时,组件将使用新语言重新渲染。对于您的redux存储中的数据,组件本身不需要任何其他状态。

本文链接:https://www.f2er.com/3157743.html

大家都在问