簡體   English   中英

反應原生 redux state 更新但不在組件中呈現

[英]react native redux state update but not rendering in a component

我有 2 個名為 A 和 B 的組件,在 BI 中有一個要在組件 A 中選擇和更新的語言列表。當我從列表中更改語言時,我使用 Redux 進行 state 管理,我可以看到狀態已更新(使用redux-logger來獲取日志)。 But the problem is when I go back to Component A using react-navigation the updated state value is not updated I can see only the old value of state only

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 => ({
        actions: bindActionCreators(introActions, dispatch)
    })
  )(ScreenB);

減速器.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", "isAuthSlider": false, "requestingsliderRestore": false}}

您正在使用作為道具傳遞的值初始化 ScreenA 的ScreenA並且永遠不會更新它。 當您使用 redux 存儲當前語言時,您不需要在 ScreenA 中使用任何ScreenA 當您連接一個組件時,您會將商店中的相關數據作為道具傳遞給它。 It seems like you are trying to "override" the state by passing it in as state but that does not update the state as it will be in this.props.state rather then in this.state . 您需要做的就是將語言作為道具傳遞給ScreenA

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

然后從 props 中讀取選擇的語言:

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

當您更新商店時,組件將使用新語言重新呈現。 對於 redux 存儲中的數據,您不需要在組件本身中添加任何額外的 state。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM