React Native:TypeError:undefined不是一个对象(评估'_this.props.data.map')

时间:2019-05-13 06:30:37

标签: javascript reactjs react-native

有人知道React Native是否存在需要修复的错误,并给出以下错误:

  

反应本机:TypeError:未定义不是对象(正在评估   '_this.props.data.map')

我非常擅长此事,但我似乎无法解决为什么在组合此组件时出现此错误的原因:

import React, { Component } from "react";
import { View, Animated } from "react-native";

class Swipe extends Component {
  renderCards() {
    return this.props.data.map(item => {
      return this.props.renderCard(item);
    });
  }

  render() {
    return <View>{this.renderCards()}</View>;
  }
}

export default Swipe;

我已经通过各种调试实践检查并再次检查了问题是否出在我的动作创建者或减速器上,并且在进行各种重构之后,我发现那些问题可以正常工作。

我决定从头开始做上述组件,而在我重用另一个组件之前,我仍然遇到上述错误。

我问这是否与RN有关,因为其他人也发布了类似的问题: react-native TypeError: undefined is not an object (evaluating 'this.props.navigator.push')

,但从未获得任何有效的帮助。

this并不是范围问题,因为如果我这样重构它:

renderCards = () => {
    return this.props.data.map(item => {
      return this.props.renderCard(item);
    });
  };

它对我绝对没有任何作用,同样的错误消息。消息也说不是对象也令人困惑,它是一个数组,map()只能遍历数组,因此不确定不是对象的对象有什么关系,请帮忙。

在此屏幕中正在调用上述组件:

import React, { Component } from "react";
import { View, Text } from "react-native";
import { connect } from "react-redux";
import Swipe from "../components/Swipe";

class DeckScreen extends Component {
  renderCard(job) {
    return (
      <Card title={job.title}>
        <View style={styles.detailWrapper}>
          <Text>{job.company}</Text>
          <Text>{job.post_date}</Text>
        </View>
        <Text>
          {job.description.replace(/<span>/g, "").replace(/<\/span>/g, "")}
        </Text>
      </Card>
    );
  }

  render() {
    return (
      <View>
        <Swipe data={this.props.jobs} renderCard={this.renderCard} />
      </View>
    );
  }
}

const styles = {
  detailWrapper: {
    flexDirection: "row",
    justifyContent: "space-around",
    marginBottom: 10
  }
};

function mapStateToProps({ jobs }) {
  return { jobs: jobs.listing };
}

export default connect(mapStateToProps)(DeckScreen);

动作创建者的外观如下:

import axios from "axios";
// import { Location } from "expo";
import qs from "qs";

import { FETCH_JOBS, LIKE_JOB } from "./types";
// import locationify from "../tools/locationify";

const JOB_ROOT_URL = "https://authenticjobs.com/api/?";

const JOB_QUERY_PARAMS = {
  api_key: "5634cc46389d0d872723b8c46fba672c",
  method: "aj.jobs.search",
  perpage: "10",
  format: "json"
};

const buildJobsUrl = () => {
  const query = qs.stringify({ ...JOB_QUERY_PARAMS });
  return `${JOB_ROOT_URL}${query}`;
};

export const fetchJobs = (region, callback) => async dispatch => {
  try {
    const url = buildJobsUrl();
    let { data } = await axios.get(url);
    dispatch({ type: FETCH_JOBS, payload: data });
    callback();
  } catch (e) {
    console.log(e);
  }
};

export const likeJob = job => {
  return {
    payload: job,
    type: LIKE_JOB
  };
};

和减速器:

import { FETCH_JOBS } from "../actions/types";

const INITIAL_STATE = {
  listing: []
};

export default function(state = INITIAL_STATE, action) {
  switch (action.type) {
    case FETCH_JOBS:
      return action.payload;
    default:
      return state;
  }
}

并且combineReducer也已正确设置:

import { combineReducers } from "redux";
import auth from "./auth_reducer";
import jobs from "./jobs_reducer";
import likedJobs from "./likes_reducer";

export default combineReducers({
  auth,
  jobs,
  likedJobs
});

listing: []基于我得到的响应的结构。当我console.log(data);时,我关心的实际数据在listing属性中。因此,我将INITIAL_STATE设置为默认列表是一个空数组,目的是确保可以映射到该数组,而不用担心尚未提取作业列表的情况。当我直接转到API端点时,您可以在下面看到它: enter image description here

3 个答案:

答案 0 :(得分:0)

我认为问题很简单,就是 private async Task<DialogTurnResult> PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken); } 没有定义。您的初始状态定义为 private async Task<DialogTurnResult> LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { // Get the token from the previous step. Note that we could also have gotten the // token directly from the prompt itself. There is an example of this in the next method. var tokenResponse = (TokenResponse)stepContext.Result; if (tokenResponse != null) { await stepContext.Context.SendActivityAsync(MessageFactory.Text("You are now logged in."), cancellationToken); return await stepContext.PromptAsync(nameof(ConfirmPrompt), new PromptOptions { Prompt = MessageFactory.Text("Would you like to view your token?") }, cancellationToken); } await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful please try again."), cancellationToken); return await stepContext.EndDialogAsync(cancellationToken: cancellationToken); } ,但是您的mapStateToProps做this.props.jobs

尝试将initialState更改为{ listing: [] },以便它始终在您的第一个渲染上起作用。

我认为您的mapStateToProps应该是:

{ jobs: ... }

编辑 实际上,如果您在化简器中正确地“命名”状态,则可能会更好,例如:

{ jobs: [] }

然后在您的mapStateToProps中:

mapStateToProps = (state) => {
  return { jobs: listings.listing }
}

答案 1 :(得分:0)

问题出在您的减速器中。请参考以下更改:

import { FETCH_JOBS } from "../actions/types";

const INITIAL_STATE = {
  listing: []
};

export default function(state = INITIAL_STATE, action) {
  switch (action.type) {
    case FETCH_JOBS:
      const { listings } = action.payload
      return {...state, listing: listings.listing}
    default:
      return state;
  }
}

希望这会有所帮助。

答案 2 :(得分:-1)

function mapStateToProps({ jobs }) {

return { jobs: jobs.listing }; }

上面让您感到困惑的是尝试下面的一个

尝试放置

function mapStateToProps( state ) { return { jobs: state.jobs.listing }; }

如您对减速器的定义,如下所示

export default combineReducers({

auth, jobs, likedJobs });

工作是您访问减少工作机会

的变量