【问题标题】:React .map is not a functionReact .map 不是函数
【发布时间】:2017-06-15 18:21:22
【问题描述】:

我正在尝试学习 React,并且在 Javascript 方面我是初学者。现在我正在开发一个从 Flickr 的 API 获取数据的应用程序。问题是当我尝试在 Main.js 组件中的道具上使用 map 方法时,我收到一条错误消息“未捕获的 TypeError:this.props.photos.map 不是函数”。在 Stackoverflow 上搜索后,我认为问题在于 this.props 是 javascript 对象而不是数组。问题是我不知道如何使它成为一个数组。谁能解释我做错了什么?

我的代码:

class App extends Component {

  constructor() {
  super();
  this.state = {

  }
}

componentDidMount() {

let apiKey = 'xxxxxxxxxxxxxxxxxx';
let searchKeyword = 'nature';
let url = `https://api.flickr.com/services/ 
           rest/?api_key=${apiKey}&method=flickr.photos.
           search&format=json&nojsoncallback=1&&per_page=50
           &page=1&text=${searchKeyword}`;

fetch(url)
  .then(response => response.json())
  .then(data => data.photos.photo.map((x) => {

    this.setState({
      farm: x.farm,
      id: x.id,
      secret: x.secret,
      server: x.server})
   // console.log(this.state)
  }))
 }

    render() {
      return (
        <div className="App">
          <Header />
          <Main img={this.state.photos} />
          <Navigation />
        </div>
      );
    }
  }

  export default class Main extends Component {

  render() {

    return(
      <main className="main">
        {console.log(this.props.photos)}
      </main>
    )
  }
 }

编辑: 为什么 this.props.img 先未定义?

Screen shot from console.log(this.props.img)

【问题讨论】:

  • 什么是photomapArray 的一个方法。
  • '我收到一条错误消息:“未捕获的 TypeError:this.props.photos.map 不是函数”' this.props.photos.map 没有出现在您引用的代码中的任何位置. data.photos.photo.map 有,你是这个意思吗?
  • 另外:您正在调用 map 并且在 map 回调中,您正在调用 setState 并且没有返回任何值,因此您将每个条目映射到 undefined;你也根本没有使用map 的返回值(你从then 中返回它,但是没有使用得到的承诺,所以它没有被使用)。你几乎肯定不想像那样反复调用setState
  • 网址真的有换行符吗?那将无法正常工作。

标签: javascript reactjs


【解决方案1】:
fetch(url)
  .then(response => response.json())
  .then(data => data.photos.photo.map((x) => {

    this.setState({
      farm: x.farm,
      id: x.id,
      secret: x.secret,
      server: x.server})
  }))

发生的情况是,您的 promise 中的 map 函数正在为返回的每张照片重置组件的状态。因此,您的状态将始终是您返回的照片列表中的最后一个对象。

这是我所指的更简化的示例

const testArray = [1,2,3,4];

let currentState;

testArray.map((value) => currentState = value)

console.log(currentState);

你想做的是这个

const testArray = [1,2,3,4];

let currentState;

//Notice we are using the return value of the map function itself.
currentState = testArray.map((value) => value)

console.log(currentState);

对于您要完成的任务,您希望您的状态是 map 函数的结果(因为它会从 map 中返回一个结果数组)。像这样的:

fetch(url)
  .then(response => response.json())
  .then(data => 
    this.setState({
      photos:
        data.photos.photo.map((x) => ({
          farm: x.farm,
          id: x.id,
          secret: x.secret,
          server: x.server
        }))
     })
   )

【讨论】:

  • 感谢您的回答。当我尝试在 Main 组件中的 this.props 上使用 map 方法时,仍然收到错误消息“map is not a function”。我想要做的是为 this.state 中的每个对象创建一个新的 img-tag。
    {this.props.photos.map((x) => { return farm{x.farm}.staticflickr.com/{x.server}/{x .id}_{x.secret}.jpg" alt="" /> })}
  • 如果你控制台 this.props.photos,它会返回什么?
  • 对象列表。问题是它不是数组吗?对象 {0:对象,1:对象,2:对象,3:对象,4:对象,5:对象,6:对象,7:对象,8:对象,9:对象,10:对象,11:对象, 12:对象,13:对象,14:对象,15:对象,16:对象,17:对象,18:对象,19:对象,20:对象,21:对象,22:对象,23:对象,24:对象,25:对象,26:对象,27:对象,28:对象,29:对象,30:对象,31:对象,32:对象,33:对象,34:对象,35:对象,36:对象, 37:对象,38:对象}
  • 深入研究,看起来 React 的状态需要是一个对象。我已经在底部更新了我的解决方案以反映这一点。本质上,只需将数组添加到属性中并将该属性传递给您的子组件。
  • 我非常感谢所有的帮助,并对所有问题表示歉意。尝试映射时我仍然遇到相同的错误。可能是因为 this.props.img 首先是未定义的(请参阅我第一个问题底部上传的图片)?请注意,我将属性名称从 photos 更改为 img。
【解决方案2】:

如果您尝试提供除.map() 期望的数组以外的其他内容,即使您正确声明了变量类型,也可能会发生此错误。一个基于钩子的例子:

const [myTwinkies, setMyTwinkies] = useState<Twinkies[]>([]);

useEffect(() => {
  // add a twinky if none are left in 7eleven
  // setMyTwinkies(twinkiesAt711 ?? {}); // ---> CAUSES ".map is not a function"
  setMyTwinkies(twinkiesAt711 ?? [{}]); 
}, [twinkiesAt711, setMyTwinkies]);

return (<ul>
  {myTwinkies.map((twinky, i)=> (
    <li key={i}>Twinky {i}: {twinky?.expiryDate}</li>
  ))}
</ul>)

【讨论】:

    【解决方案3】:

    在查看地图之前,只需检查数组的长度即可。如果 len 大于 0 则继续,否则忽略它。

    data.photos.photo.map.length>0 && data.photos.photo.map(........)
    

    【讨论】:

      猜你喜欢
      • 2016-09-02
      • 1970-01-01
      • 2017-08-16
      • 1970-01-01
      • 2017-10-26
      • 1970-01-01
      • 2020-09-20
      • 2020-07-26
      • 1970-01-01
      相关资源
      最近更新 更多