Контекстный API в React Native

Привет, ребята, я только начинаю изучать React native context api Я хочу знать, как я могу реализовать это глобально, как глобальное состояние и он также не работает после перехода на другой экран, и почему мы включаем имя класса в поставщик <ProfileScreen screen= {this.state.contextData}/>, можем ли мы сделать это глобально .. вот мой код

global.cart=1
const Context = React.createContext(global.cart)

class HomeScreen extends Component<Props> {
    constructor(props){
      super(props);
      this.state = {
            contextData:5
           }
      }

      Incrementhome=()=>{

        this.setState({contextData:global.cart})
          global.cart++
      }
      Decrementhome=()=>{
        this.setState({contextData:global.cart})
        global.cart--
      }
  render() {
    return (
      <View>
      <Context.Provider value = {this.state.contextData}>
        <Button title = "Incrementhome"
          onPress = {this.Incrementhome}/>
          <Button title = "decrementhome"
            onPress = {this.Decrementhome}/>

<ProfileScreen screen= {this.state.contextData}/>
      </Context.Provider>
<Button title='sd' onPress = {()=>{this.props.navigation.navigate('Profile')}}/>

      </View>
    )
  }
}

экран профиля класса, который может отображать мои данные

class ProfileScreen extends Component<Props> {
  render() {
  return (
      <View style = {{}}>
        <Context.Consumer>
          {data=>  <Text style = {{fontSize:50}}>{data}</Text>}
        </Context.Consumer>
      </View>
    );
  }
}

экраны профиля класса, который также является поставщиком

class ProfileScreens extends Component<Props> {
    static navigationOptions =
  {
     title: 'MainActivity',  header: <Button title='sd' onPress = {()=>{this.props.navigation.navigate('ProfileScreen')}}/>
   };
  constructor(props){
    super(props);

    this.state = {contextData:0
        }

    }

  render() {
    return (
      <View >
        <Context.Provider value = {this.state.contextData}>
          <Button title = "decrement" onPress = {()=>{ this.props.changeHomeScreen() }}/>
          <Button title='sd' onPress = {()=>{this.props.navigation.navigate(Profile)}}/>
        </Context.Provider>
      </View>
    );
  }
}

мой навигатор

export default HomeScreen = createStackNavigator({
  HomeScreen:{
    screen:HomeScreen
  },
    Profile:{
      screen:ProfileScreen
    },
      ProfileScreens:{
        screen:ProfileScreens
      },
})
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
6 627
1

Ответы 1

Извините, но вы плохо реализовали React Context API. Прочтите это https://medium.com/@mcssym/react-context-api-why-you-dont-surely-need-redux-co-e6d96ca8abca?source=linkShare-1d75ea07b723-1539164899

Способ передачи contextData через опору screen бесполезен, если вы используете Context.Consumer.

navigation.navigate принимает в качестве параметра нить, а не Компонент React.

Я действительно не знаю, как вам легко объяснить, поэтому я перепишу ваш код, указав, как вы должны выполнять эту работу.

ВАШ НАВИГАТОР (где-то / navigation.js)

export default Home = createStackNavigator({
    HomeScreen:{
        screen: HomeScreen
    },
    Profile:{
        screen: ProfileScreen
    },
    ProfileScreens:{
        screen: ProfileScreens // Don't need to be a Provider
    },
})

Ваш ProfileScreens не обязательно должен быть провайдером, потому что вы не используете его в качестве оболочки. Но может быть Потребителем, потому что вы используете contextData. Я думаю, это то же самое, что и на вашем домашнем экране, и на том, который вы хотите сделать глобальным.

//IMPORTANT
import { withHomeContext } from './somewhere/contexts/home';

class ProfileScreens extends Component<Props> {
    static navigationOptions = {
               title: 'MainActivity',  
               header: <Button title='sd' onPress = {()=> this.props.navigation.navigate('ProfileScreen')}/>
           };
    constructor(props){
        super(props);

        this.state = {
            contextData: props.homeProvider.contextData // Get from global context home provider
        };
    }

    decrementHome = () => {
        // Calling decrement from homeProvider
        if (this.props.homeProvider) this.props.homeProvider.decrement();
    }

    render() {
        return (
            <View >
                {/*You must call the decrementHome from your provider*/}
                <Button title = "decrement" onPress = {this.decrementHome}/>
                <Button title='sd' onPress = {()=> this.props.navigation.navigate('ProfileScreen') }/>
            </View>
        );
    }
}

export default withHomeContext(ProfileScreens);

ВАШ ProfileScreen. Вы должны изменить способ его создания как Потребитель. Лучше использовать функцию withHomeContext, созданную в вашем классе HomeContext.

//IMPORTANT
import { withHomeContext } from './somewhere/contexts/home';

class ProfileScreen extends Component<Props> {
    render() {
        return (
            <View style = {{}}>
                <Text style = {{fontSize:50}}>{this.props.homeProvider.contextData}</Text>
            </View>
        );
    }
}

export default withHomeContext(ProfileScreen);

И, наконец, ваш HomeContext с вашим поставщиком и потребителем может быть:

// In Your context/home.js

const HomeContext = React.createContext();


export class HomeProvider extends React.Component {

    state = {
        contextData: 5 //Default Value
    };


    decrementHome = () => {
        this.setState(prevState => {
            contextData: prevState.contextData - 1;
        });
    }

    incrementHome = () => {
        this.setState(prevState => {
            contextData: prevState.contextData + 1;
        });
    }

    getValues = () => {
        return {
            contextData: this.state.contextData,
            decrement: this.decrementHome, // Call via homeProvider prop
            increment: this.incrementHome // Call via homeProvider prop
        }
    }

    render() {
        return (
            <HomeContext.Provider value = {this.getValues()}>
                {this.props.children}
            </HomeContext.Provider>
        );
    }
}

export function withHomeContext(Component) {
    class ComponentWithContext extends React.Component {
        render {
            return (
                <HomeContext.Consumer>
                    {(value) => <Component {...this.props} homeProvider = {value} />
                </HomeContext.Consumer>
            );
        };
    }

    return ComponentWithContext;
}

Теперь в вашем корневом приложении

import { HomeProvider } from './somwhere/context/home';
import Home from './somwhere/navigation';

export default class App extends React.Component {

    render() {
        return (
            <HomeProvider>
                <Home />
            </HomeProvider>
        );
    }

}

не могли бы вы уточнить .. это потому что я не могу это понять

Tanveerbyn 10.10.2018 12:04

Другие вопросы по теме