【问题标题】:Context API in react nativeReact Native 中的上下文 API
【发布时间】:2018-10-10 07:24:09
【问题描述】:

大家好,我刚开始学习 React 本机上下文 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
      },
})

【问题讨论】:

    标签: reactjs react-native react-native-android react-native-ios


    【解决方案1】:

    抱歉,您没有很好地实现 React Context API。阅读此https://medium.com/@mcssym/react-context-api-why-you-dont-surely-need-redux-co-e6d96ca8abca?source=linkShare-1d75ea07b723-1539164899

    如果你使用Context.Consumer,你通过screen prop 传递contextData 的方式是没有用的。

    navigation.navigate 采用 string 而不是 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。我想这与您的 HomeScreen 中的相同,并且您要使其全球化。

    //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。您必须更改作为消费者创建它的方式。最好使用在 HomeContext 类中创建的函数 withHomeContext

    //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 与您的 Provider 和 Consumer 可能是:

    // 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>
            );
        }
    
    }
    

    【讨论】:

    • 你能详细说明一下吗..这个因为我听不懂
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多