React Native: динамически менять стиль с помощью AsyncStorage и States - PullRequest
0 голосов
/ 20 марта 2019

Я хочу реализовать темный режим и черный режим в моем приложении, и способ, которым я имею это, состоит в том, что пользователь переключает на темный / черный режим из одного класса, в котором я хочу, чтобы состояние было обновлено для всех классов, переключательКласс выглядит следующим образом:

Класс 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, но не на экран SettingsScEN ЕСЛИ Я не обновляю приложение.Есть ли способ сделать это, чтобы все они были затронуты мгновенно?

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Дело в том, что в AppearanceToggleScreen вы меняете состояние, поэтому компонент перерисовывается (с новой темой), а потому что SettingsScreen уже находится в стеке навигации (потому что там вы находитесьпереход от) componentDidMount больше не выполняется.

Теперь, возможно, вы хотите использовать Context API для доступа к значениям глобально или сделать что-то вроде this .

1 голос
/ 20 марта 2019

Возможно, лучший способ его распространения - это прослушать изменения в вашем AppComponent, используя 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>
    );
  }
}

Подробнее читать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...