React Native:使用AsyncStorage和States动态更改样式

问题描述 投票:0回答:2

我想在我的应用程序中实现黑暗模式和黑色模式,我的方式是用户在一个类中切换黑暗/黑色模式,我希望状态更新到所有类,切换类是其次:

AppearanceToggle类

  state = {
    BlackModeValue: null,
    DarkModeValue: null
  };
  componentDidMount = () => {
    AsyncStorage.getItem('DarkModeValue').then(value => this.setState({ DarkModeValue: JSON.parse(value) }));
    AsyncStorage.getItem('BlackModeValue').then(value => this.setState({ BlackModeValue: JSON.parse(value) }));
  };

  //AsyncStorage.setItem .........

  render() {
    return (

      <ScrollView style={[ styles.View , this.state.DarkModeValue ?  darkmode.ASView : null || this.state.BlackModeValue ? blackmode.ASView : null ]}>
          <SettingsList borderColor='#c8c7cc' defaultItemSize={50}>              
             <SettingsList.Item
              hasSwitch={true}
              switchState={this.state.DarkModeValue}
              switchOnValueChange={//Goes to asyncStorage.setItem method}
              title='Dark Mode'
            />
           <SettingsList.Item
             hasSwitch={true}
             switchState={this.state.BlackModeValue}
             switchOnValueChange={//Goes to asyncStorage.setItem method}
             title='Black Mode'
           />
          </SettingsList>
      </ScrollView>
    );
  }
}

然后在类中(这是SettingsScreen.js,这是导航到AppearanceToggle的屏幕)我想要.getItem并更改状态如下:

  state = {
      switchValue: false,
      rated: false,
      DarkModeValue:null,
      BlackModeValue:null,
    };
  componentDidMount = () => {
    AsyncStorage.getItem('DarkModeValue').then(value => this.setState({ DarkModeValue: JSON.parse(value) }));
    AsyncStorage.getItem('BlackModeValue').then(value => this.setState({ BlackModeValue: JSON.parse(value) }));
  };
  render() {
    return (
      <ScrollView style={[ styles.View , this.state.DarkModeValue ?  styles.DMView : null || this.state.BlackModeValue ? styles.BMView : null ]}>
        ..........
       </ScrollView>

我遇到的问题是,当我更改开关时,它会立即影响AppearanceToggleScreen类,但不会影响SettingsScreen,除非我刷新应用程序。有办法做到这一点,所有这些都会立即受到影响吗?

css react-native switch-statement asyncstorage
2个回答
1
投票

也许传播它的最好方法是使用AppComponent或root组件来监听Context中的变化。例如

所以你会创建一个主题上下文,如:

export const themes = {
  blackMode: {
    foreground: '#000000',
    background: '#eeeeee',
  },
  darkMode: {
    foreground: '#2f4f4ff',
    background: '#222222',
  },
};

export const ThemeContext = React.createContext(
  themes.darkMode // default value
)

;

你的AppearanceToggle课程会有类似的东西:

import {ThemeContext} from './theme-context';

class ThemedButton extends Component {
  render() {
    let props = this.props;
    let theme = this.context;
    return (
      <button
        {...props}
        style={{backgroundColor: theme.background}}
      />
    );
  }
}
ThemedButton.contextType = ThemeContext;

export default ThemedButton;

然后你的AppComponent可能

    import {ThemeContext, themes} from './theme-context';
    import ThemedButton from './themed-button';



    function Toolbar(props) {
      // Render your customized toolbar here and bind the changeTheme function to it
    }


class App extends Component {
  constructor(props) {
    super(props);
   };

  componentDidMount = () => {
     AsyncStorage.getItem('selectedTheme').then(value => this.setState({ selectedTheme: JSON.parse(value) }));
  };


    this.toggleTheme = () => {
      this.setState(state => ({
        theme:
          state.theme === themes.darkMode
            ? themes.blackMode
            : themes.darkMode,
      }));
    };
  }

  render() {
    // The ThemedButton button inside the ThemeProvider
    // uses the theme from state while the one outside uses
    // the default dark theme
    return (
      <Page>
        <ThemeContext.Provider value={this.state.theme}>
          <Toolbar changeTheme={this.toggleTheme} />
        </ThemeContext.Provider>
        <Section>
          <ThemedButton />
        </Section>
      </Page>
    );
  }
}

更多read


1
投票

事情是,在AppearanceToggleScreen你正在改变状态,因此组件被重新渲染(使用新主题),但因为SettingsScreen已经在导航堆栈中(因为那是你导航的地方)componentDidMount不是再次执行。

现在,也许您想使用Context API全局访问值,或者执行类似this的操作。

© www.soinside.com 2019 - 2024. All rights reserved.