Контекст API в нативной реакции - PullRequest
0 голосов
/ 10 октября 2018

Привет, ребята, я только начинаю изучать 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
      },
})

1 Ответ

0 голосов
/ 10 октября 2018

Извините, но вы плохо реализовали 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 Component в качестве параметра.

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

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

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

Ваш профиль ScreenScreens Не нужно быть провайдером, потому что вы не используете его в качестве оболочки.Но может быть потребителем, потому что вы используете 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>
        );
    }

}
...