无法在上下文中找到“store”或者在React Native中找到它们

时间:2017-09-14 17:29:44

标签: javascript reactjs react-native redux

我正在尝试将Redux集成到我的React Native应用程序中。我收到错误“无法找到”商店“在上下文或道具”

我的代码如下:

index.js

import { AppRegistry, View } from 'react-native'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import { reducer } from './containers/intro/introRedux'

const store = createStore(reducer);

import App from './App'

const AppWithStore = () => (
    <Provider store={store}>
      <App  />
    </Provider>
)

AppRegistry.registerComponent('App', () => AppWithStore)

App.js

//Components & Dependencies
import React, { Component } from 'react';
import { TextInput, Picker, TouchableOpacity, Image, AppRegistry, StyleSheet, Text, View } from 'react-native';
import Swiper from 'react-native-swiper';

import { connect } from 'react-redux'
import { actionCreators } from './containers/intro/introRedux'


const mapStateToProps = (state) => ({
  todos: state.todos,
})

//Styles
var introStyle = require('./containers/intro/styles');

class App extends Component {
  profile = {
    gender: "Female",
    heightUnit: "cm",
    weightUnit: "kg"
  }

  saveProfile() {
    alert(JSON.stringify(this.profile));
  }

  render() {
    return (
      <Swiper ref={(component) => { this.swiper = component; }} dotColor='#2A2D2E' activeDotColor='#FFF' showsButtons={false} loop={false}>
        <View style={introStyle.slide1}>
          <Image source={require('./images/logo.png')} />
          <Text style={introStyle.header}>Build Muscle, Burn Fat &amp; Get Stronger</Text>
          <TouchableOpacity style={introStyle.nextButton} onPress={() => this.swiper.scrollBy(1)}>
            <Text style={introStyle.nextButtonText}>Next</Text>
          </TouchableOpacity>
        </View>
        <View style={introStyle.slide2}>
          <View style={introStyle.wrapper}>
            <Text style={introStyle.header}>Let's setup your profile</Text>
            <Text style={introStyle.subHeader}>Tell us a little about yourself first</Text>

            <Picker
              selectedValue={this.profile.gender}
              mode='dropdown'
              style={[introStyle.dropdown, introStyle.genderDropdown]}>
              <Picker.Item label="Male" value="Male" />
              <Picker.Item label="Female" value="Female" />
            </Picker>

            <TextInput
              style={introStyle.textInput}
              underlineColorAndroid='#FFF'
              placeholder='Age'
              keyboardType='numeric'
              maxLength={2}
              value={this.profile && this.profile.age}
            />

            <View style={{ flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'flex-start' }}>
              <TextInput
                style={introStyle.textInput}
                underlineColorAndroid='#FFF'
                placeholder='Height'
                keyboardType='numeric'
                maxLength={3}
                value={this.profile && this.profile.height}
              />
              <Picker
                mode='dropdown'
                style={introStyle.dropdown}
                selectedValue={this.profile.heightUnit}
              >
                <Picker.Item label="cm" value="cm" />
                <Picker.Item label="inch" value="inch" />
              </Picker>
            </View>

            <View style={{ flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'flex-start' }}>
              <TextInput
                style={introStyle.textInput}
                underlineColorAndroid='#FFF'
                placeholder='Weight'
                keyboardType='numeric'
                maxLength={3}
                value={this.profile && this.profile.weight}
              />
              <Picker
                mode='dropdown'
                style={introStyle.dropdown}
                selectedValue={this.profile.weightUnit}
              >
                <Picker.Item label="kg" value="kg" />
                <Picker.Item label="lb" value="lb" />
              </Picker>
            </View>
            <TouchableOpacity style={introStyle.nextButton} onPress={() => this.saveProfile()}>
              <Text style={[introStyle.nextButtonText, { textAlign: 'center' }]}>Let's go!</Text>
            </TouchableOpacity>
          </View>
        </View>
      </Swiper>
    );
  }
}

export default connect(mapStateToProps)(App)

introRedux.js

const initialState = {
    todos: ['Click to remove', 'Learn React Native', 'Write Code', 'Ship App'],
}

export const actionCreators = {
    UPDATE_GENDER: 'UPDATE_GENDER',
};

export const reducer = (state = initialState, action) => {
    const {profile} = state
    const {type, payload} = action

    switch (type) {
        case types.ADD: {
          return {
            ...state,
            todos: [payload, ...todos],
          }
        }
        case types.REMOVE: {
          return {
            ...state,
            todos: todos.filter((todo, i) => i !== payload),
          }
        }
    }

    return state
}

为什么应用程序无法从提供商处找到商店?我很茫然。

编辑:直接传递商店:

import { AppRegistry, View } from 'react-native'

import { createStore } from 'redux'
import { Provider } from 'react-redux'

import { reducer } from './containers/intro/introRedux'

const store = createStore(reducer)

// Import the App container component
import App from './App'

// Pass the store into the app container
const AppWithStore = () => <App store={store} />

AppRegistry.registerComponent('App', () => AppWithStore)

如果我直接通过商店,“App”不会使用connect来导出组件

1 个答案:

答案 0 :(得分:0)

替换

const AppWithStore = () => (
    <Provider store={store}>
      <App  />
    </Provider>
)

使用类组件:

class AppWithStore extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <App />
      </Provider>
    )
  }
}

功能组件不保持状态。我认为AppRegistry.registerComponent需要您使用类组件。

<强> EDIT2

{
  "name": "vtapered",
  "version": "0.1.0",
  "private": true,
  "devDependencies": {
    "react-native-scripts": "1.3.1",
    "jest-expo": "~20.0.0",
    "react-test-renderer": "16.0.0-alpha.12"
  },
  "main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
  "scripts": {
    "start": "react-native-scripts start",
    "eject": "react-native-scripts eject",
    "android": "react-native-scripts android",
    "ios": "react-native-scripts ios",
    "test": "node node_modules/jest/bin/jest.js --watch"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "expo": "^20.0.0",
    "react": "16.0.0-alpha.12",
    "react-native": "^0.48.0",
    "react-native-swiper": "^1.5.10",
    "react-redux": "^5.0.6"
  }
}