React .map 不是一个函数

IT技术 javascript reactjs
2021-05-02 08:04:50

我正在尝试学习 React,而且我是 Javascript 的初学者。现在我正在开发一个从 Flickr 的 API 获取数据的应用程序。问题是,当我尝试在 Main.js 组件中的props上使用 map 方法时,我收到一条错误消息“未捕获的类型错误: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 首先未定义?

来自 console.log(this.props.img) 的屏幕截图

3个回答
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中的地图功能正在为返回的每张照片重置组件的状态。因此,您的状态将始终是您返回的照片列表中的最后一个对象。

这是我所指的一个更简化的例子

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

如果您尝试提供.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>)

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

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