状态变化时,不会在道具中获取值

时间:2018-02-27 04:55:39

标签: react-native react-redux

我是反应原生的redux的新手,我正在更新我在Redux架构中使用flux模式构建的旧代码,我正在学习store,thunk,redurs和Actions的使用,这里有一些我的类我更新了: -

HomeScreenClass : -

import React, { Component } from "react";
import {
  StyleSheet,
  View,
  StatusBar,
  ActivityIndicator,
  Modal,
  Platform,
  Image,
  ScrollView,
  TouchableOpacity
} from "react-native";
import { Card } from "native-base";
import NavigationDrawer from "../../component/navigationDrawerComponent/NavigationDrawer";
import CategoryProductList from "../HomeScreen/screens/CategoryProducts";
import CustomText from "../../component/customComponent/CustomText";
import ProductScreen from "./screens/ProductScreen";
import ProductDetailScreen from "./screens/ProductDetailScreen";
import PopUpMenu from "../../component/navigationDrawerComponent/PopUpMenu";
import { Font } from "expo";
import LoginScreen from "../AuthScreen/LoginScreen";
import SignUp from "../AuthScreen/SignUpScreen";
import WebApi from "../../component/webServiceComponent/WebServiceHandler";
import ForgotPassword from "../AuthScreen/ForgotPassword";
import SignUpScreen from '../AuthScreen/SignUpScreen';
import ProfileScreen from "./screens/ProfileScreen";
import ChangePassword from "../AuthScreen/ChangePassword";
import EditProfileScreen from "./screens/EditProfileScreen";
import HtmlView from "./screens/HtmlView";
import OfflineNotice from "../../component/internetCheckComponent/OfflineNotice";
import { createRouter, NavigationProvider } from "@expo/ex-navigation";
import metrics from "../../component/displaySizeComponent/metrics";
import { connect } from 'react-redux';
import { HitAllApis} from '../../actions/ApiCallActions';
var self;

export const Router = createRouter(() => ({
         about: () => AboutScreen,
         products: () => ProductScreen,
         aboutUs: () => AboutUs,
         terms: () => Terms,
         rateUs: () => RateUs,
         productDetails: () => ProductDetailScreen,
         ProductListing: () => CategoryProductList,
         feedback: () => Feedback,
         htmlView: () => HtmlView,
         loginScreen: () => LoginScreen,
         signUpScreen: () => SignUpScreen,
         profileScreen: () => ProfileScreen,
         editProfileScreen: () => EditProfileScreen,
         forgotPasswordScreen: () => ForgotPassword,
         changePassword: () => ChangePassword
       }));

class HomeScreen extends Component {
  constructor(props) {
    super(props);
    this.state={
      modalVisible: false,
      loaded: false
    }
    self = this;
  }

  componentWillMount() {
    console.disableYellowBox = true;
    self._loadFontsAsync();
    const {dispatch} = this.props;
    dispatch(HitAllApis());
  }
componentDidMount() {
  console.log("component*****" , this.props);
}
  closeModal() {
    this.setState({ modalVisible: false });
  }
  openModal() {
    if (this.state.modalVisible) {
      this.setState({ modalVisible: false });
    } else {
      this.setState({ modalVisible: true });
    }
  }

  _loadFontsAsync = async () => {
    await Font.loadAsync({
      futuraLigtBt: require("../../fonts/futuraLightBt.ttf")
    });
    this.setState({ loaded: true });
  };
  render() {
    console.log("under Render ", this.props)
    if (!this.props.showData || !this.state.loaded) {
      return (
        <View style={{ flex: 1 }}>
          <Image
            style={{
              height: metrics.DEVICE_HEIGHT + 24,
              width: metrics.DEVICE_WIDTH
            }}
            source={require("../../assets/splash.png")}
          />
          <ActivityIndicator
            color="white"
            style={styles.activityIndicator}
            size="small"
            animating={this.props.isLoading}
          />
          <OfflineNotice />
        </View>
      );
    }
    return (

      <View style={styles.container}>
        <NavigationProvider router={Router}>
          <StatusBar barStyle="default" hidden={false} />
          <NavigationDrawer
            openMenu={() => this.openModal()}
            disableBack={true}
            magentoData={this.props.magentoData}
            bannerData={this.props.bannerData}
            categoryList={this.props.categoryList}
          />
        </NavigationProvider>
        <Modal
          transparent={true}
          visible={this.state.modalVisible}
          animationType={"none"}
          onRequestClose={() => this.closeModal()}
        >
          <View style={styles.modalContainer}>
            <View style={styles.modalInnerContainer}>
              <TouchableOpacity
                style={styles.navBar}
                onPress={() => this.closeModal()}
              />
              <View style={{ flex: 1, backgroundColor: "white" }}>
                <Card>
                  <ScrollView showsVerticalScrollIndicator={false}>
                    <View style={styles.scrollView}>
                      <PopUpMenu
                        popUpList={this.state.popUpPageData}
                        closePopUp={() => this.closeModal()}
                      />
                    </View>
                  </ScrollView>
                </Card>
              </View>
            </View>
            <TouchableOpacity
              style={{ flex: 0.5, color: "transparent" }}
              onPress={() => this.closeModal()}
            />
          </View>
        </Modal>
        <OfflineNotice />
      </View>
    );
  }
}


function mapStateToProps(state) {
  //const { magentoData: [],showData,isLoading,popUpPageData: [],categoryList: [],bannerData: [],loaded,modalVisible} = state

  return {
    state
  }
}

export default connect(mapStateToProps)(HomeScreen)

const styles = StyleSheet.create({
  modalInnerContainer: {
    flex: 0.5,
    justifyContent: "center",
    backgroundColor: "transparent",
    flexDirection: "column"
  },
  container: { flex: 1, justifyContent: "center", alignItems: "center" },
  activityIndicator: { position: "absolute", bottom: 20, alignSelf: "center" },
  navBar: {
    ...Platform.select({
      ios: {
        height: 63
      },
      android: {
        height: 55
      }
    }),
    color: "transparent"
  },
  container: {
    flex: 1,
    backgroundColor: "white",
    alignItems: "center",
    justifyContent: "center"
  },
  scrollView: {
    flex: 1,
    borderRadius: 3,
    justifyContent: "flex-start",
    backgroundColor: "white",
    shadowColor: "black",
    shadowOpacity: 0.2,
    shadowRadius: 3,
    shadowOffset: {
      height: 0,
      width: 0
    }
  },
  modalContainer: {
    flex: 1,
    flexDirection: "column",
    justifyContent: "center",
    backgroundColor: "transparent"
  }
});

在上面的类中,我使用了Ex-natvigation,我已将此类与Reducer连接。在上面,当我尝试通过export default connect(mapStateToProps,{HitAllApis})(HomeScreen)更新连接线时,它显示了语法错误。

以下是我的Action类的内容: -

import * as types from '../types/ActionTypes'
import WebApi from "../component/webServiceComponent/WebServiceHandler";

function getCategorylisting() {
    console.log('category');
    return WebApi.GetApihit("/restapi/index/CategoryListing", null);
}

function getdashboard() {
    console.log('das');
    return WebApi.GetApihit("/restapi/index/getdashboard", null);
}

function getBanner() {
    console.log('Banner');
    return WebApi.GetApihit("/bannersliderapp/banner/banner", null);
}
function getStaticPages() {
    return WebApi.GetApihit("/restapi/staticpages/getPages/", null);
}

export function HitAllApis (){

    return function (dispatch) {

        WebApi.fetchHeader().then(
            function () {

                Promise.all([
                    getCategorylisting(),
                    getdashboard(),
                    getBanner(),
                    getStaticPages()
                ]).then(function (response) {

                    dispatch({ type: types.Api_Response_case, data: response });
                }, function (Error) {
                    dispatch({ type: types.Api_Request_case, data: response });
                });
            },
            function (error) {
                console.log(error);
            }
        );

    }

}

我要求我需要从多个Api获取数据,所以我在Action类中使用promise并在一个响应对象中获取数据

我的商店类: -

import {createStore, applyMiddleware} from 'redux';
import thunkMiddleware from 'redux-thunk';
import rootReducer from '../reducers/index';

const createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore);

export default function configureStore(initialState) {
    const store = createStoreWithMiddleware(rootReducer, initialState);

    return store;
}

我的减速机课程: -

import * as type from '../types/ActionTypes'

const initialState =({
    magentoData: [],
    showData: false,
    isLoading: false,
    popUpPageData: [],
    categoryList: [],
    bannerData: []   
})

export default function DashBoardData(state = initialState, action = {}) {

    switch (action.type) {
        case type.Api_Request_case:
            return state.isLoading = true;
        case type.Api_Response_case:
        state.isLoading = false;
        state.showData=true;
        state.categoryData = action.data[0];
        state.magentoData = action.data[1];
        state.bannerData = action.data[2];
        state.popUpPageData = action.data[3];
        // console.log('categoryData****', state.categoryData);
        // console.log('magentoData****', state.magentoData);
        // console.log('bannerData****', state.bannerData);
        // console.log('popUpPageData****', state.popUpPageData);
        return {...state};
        default:
            return state
    }
}

这就是我在console.log中的内容(&#34;在Render&#34;,this.props下): -

Object {
  "dispatch": [Function anonymous],
  "state": Object {
    "DashBoardData": Object {
      "bannerData": Array [],
      "categoryList": Array [],
      "isLoading": false,
      "magentoData": Array [],
      "popUpPageData": Array [],
      "showData": false,
    },
  },
}

我可能做错了,请让我知道我的方法是好还是我需要以其他方式实现这一点,如果我在这里做错了请告诉我我的错误,以便我能更清楚地理解它

任何帮助都会得到极大的赞赏!

由于

1 个答案:

答案 0 :(得分:1)

当确定旧状态与新状态不同时,React重新渲染。但是你修改旧状态,然后将其复制到你返回的新状态,所以它认为没有任何改变。

你的reducer应该只从状态对象中读取,它不应该进行修改。例如:

export default function DashBoardData(state = initialState, action = {}) {
    switch (action.type) {
        case type.Api_Request_case:
            return {
                ...state,       // old state is NOT modified
                isLoading: true // this is only set for the NEW state
            };
        case type.Api_Response_case:
            return {
                ...state,         // initially use what's in the OLD state,
                isLoading: false, // then include the vales you are changing.
                showData: true,
                categoryData: action.data[0],
                magentoData: action.data[0],
                bannerData: action.data[0],
                popUpPageData: action.data[0],
        default:
            // this REALLY means nothing has changed,
            // React will not re-render
            return state;
    }
}