2017-07-08 24 views
0

尝试将JSON文件转换为数组,然后从中随机选择5个项目。ReactJS:Uncaught ReferenceError:[功能]未定义,2017年7月

认为问题是我的渲染/返回语句在ImageContainer.js的底部,但我是一个ReactJS n00b,所以它可能是任何东西。

任何帮助或建议,非常感谢。

控制台错误

compiled.js:31562 Uncaught ReferenceError: selectImages is not defined 
    at ImageContainer.render (compiled.js:31562) 
    at compiled.js:20195 
    at measureLifeCyclePerf (compiled.js:19475) 
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (compiled.js:20194) 
    at ReactCompositeComponentWrapper._renderValidatedComponent (compiled.js:20221) 
    at ReactCompositeComponentWrapper.performInitialMount (compiled.js:19761) 
    at ReactCompositeComponentWrapper.mountComponent (compiled.js:19657) 
    at Object.mountComponent (compiled.js:4009) 
    at ReactDOMComponent.mountChildren (compiled.js:24150) 
    at ReactDOMComponent._createInitialChildren (compiled.js:21126) 

ImageContainer.js - 拉从以.json文件IMG信息,随机选择5渲染

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Image } from './Image'; 

export class ImageContainer extends React.Component { 
    constructor(props) { 
    super(props); 

    this.numImages = 5; 

    this.state = { 
     data: [] 
    }; 
    } 

    componentDidMount() { 
    $.ajax({ 
     url: '../app/data/namegame-data.json', 
     dataType: 'json', 
     success: function(data) { 
     this.setState({data: data}); 
     }.bind(this), 
     error: function(xhr, status, err) { 
     console.error('#GET Error', status, err.toString()); 
     }.bind(this) 
    }); 
    } 

    shuffleArray(array) { 
    let i = array.length - 1; 
    for (; i > 0; i--) { 
     const j = Math.floor(Math.random() * (i + 1)); 
     const temp = array[i]; 
     array[i] = array[j]; 
     array[j] = temp; 
    } 
    return array; 
    } 

    selectImages({ data }) { 
    const shuffledImages = shuffleArray(images); 
    return (
     shuffledImages.map((data, idx) => { 
     for (let i = 0; i < this.numImages; i++) { 
      if (this.state.data.length > 0) { 
       return <Image key={idx} name={data.name} src={data.src} />; 
      } 
     } 
     }) 
    ); 
    } 

    render() { 
    return {selectImages}; 
    } 
} 

Image.js - 只是图片HTML

import React from 'react'; 

export class Image extends React.Component { 
    render() { 
     const key = this.props.id; 
     const name = this.props.name; 
     const src = this.props.src; 
     return (
      <picture> 
       <img id="pic-template" className="pic" src="{src}" name="{name}" key="id" /> 
      </picture> 
     ); 
    } 
} 

[主] .js文件 - 大部分HTML的就在这里,只包括进口位

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { ImageContainer } from './ImageContainer'; 

export default class NameGame extends React.Component { 
    render() { 
    return (
     ... 
     <div id="images-wrap"> 
      <ImageContainer /> 
     </div> 
     ... 
    ); 
    } 
} 

依赖

{ 
    ... 
    "dependencies": { 
    "json-loader": "^0.5.4", 
    "react": "^15.6.1", 
    "react-dom": "^15.6.1" 
    }, 
    "devDependencies": { 
    "css-loader": "^0.28.4", 
    "extract-text-webpack-plugin": "^2.1.2", 
    "node-sass": "^4.5.3", 
    "sass-loader": "^6.0.6", 
    "style-loader": "^0.18.2", 
    "webpack": "^2.2.0", 
    "webpack-dev-server": "^2.5.0" 
    } 
} 

回答

0

我认为 “这” 是哪里出了问题;):

selectImages是ImageContainer类的一部分, 这意味着该函数在此类中的作用域,所以它应该是t his.selectImages

在渲染调用selectimages

render() { 
    return {this.selectImages()}; <-- its a function so u should call it as a function 
} 

记住selectimage应该返回一个反应成分,但如果它会返回项目的数组 反应会使你应该把它包起来,你不能PAS多重反应的元素来渲染

所以你应该像

render() { 
    return (
     <div> <-- give render 1 react component wrapping the multiple components 
      {this.selectImages()}; <-- its a function so u should call it as a function 
     </div> 
    ) 
} 

selectImages({}数据)< - 它从哪里获取数据?我不认为需要的数据,仅如果u要通十数据: '不管'}的功能

shuffledImages.map((data, idx) => { 
data will be the items from the shuffledImages array 
}) 


const shuffledImages = shuffleArray(images); should be -> 
const shuffledImages = this.shuffleArray(images); 

关于你的另一个问题

shuffleArray() { 
    (array) <-- u are mutating the data from the state, when u passed it to the function, u should only change state with setState. 

    use another shuffle function where u dont mutate the data ,use concat or es6 spread operator [ ...data ] etc . 

读: “Correct modification of state arrays in ReactJS

}

selectImages() { 
     const shuffledImages = this.shuffleArray(this.state.data); <-- u dont have to pass this.state.data, to the function ,it is accessable within shufflarray -> const shuffledImages = this.shuffleArray(); 

     return (
      shuffledImages.map((data, idx) => { 
      for (let i = 0; i < this.numImages; i++) { 
       return <Image key={idx} name={this.state.data.name} src={this.state.data.src} />; 
      } 
      }) 
    ); 
    } 

如果你的ajax调用失败数组是未定义的。并且你不能在undefined上调用长度。(多数民众赞成在错误说) - 关于你的电话

你需要告诉你的阿贾克斯呼吁做什么,这是一个职位或获得? 添加一个 '类型'(应该是类型: '得到')

或使用简写(我看到ü正在使用jQuery)

$.getJSON('whateverjson file.json').done(function(response) { 
    console.log("Success"); 
}).fail(function() { 
    console.log("Error"); 
}); 

关于数据 - >

u should parse the json setstate({ data: JSON.parse(data) }) or setstate({ data: $.parseJSON(data) }); 

我必须说,使用jQuery,结合反应,不是我应该推荐的东西,jquery主要用于dom操作,反应使用其虚拟dom,并包含整个jquery库仅用于ajax请求是一种浪费。

试“取” < ==

PS直视https://facebook.github.io/react/docs/react-api.html(反应文档)

它也最好API调用的结果传递给组件作为道具,但你会明白这一点。曾经潜入文档!我希望这可以帮助你,祝你好运m8

+0

感谢您的快速回复!绝对要靠近几步。现在的错误是:* Uncaught TypeError:无法读取未定义的属性“长度”*除了进行更改并添加更多“this”之外。前缀,我改变componentDidMount()componentWillMount(),加载,但ajax调用不成功。 – n0bodySp3cial

+0

进一步阅读表明componentDidMount()是正确的,但是JSON可能*不会被解析成任何可用的东西 - 继续破解这个。 – n0bodySp3cial

+0

查看更新后的anwser –

0

下面是ImageContainer.js的更新(大部分)工作版本,它包含了Danillo的更改并解决了随后的数组问题。这些问题主要与缺少“这个”有关。和“this.state”。

ImageContainer.js

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Image } from './Image'; 

export class ImageContainer extends React.Component { 
    constructor(props) { 
     super(props); 

     this.numImages = 5; 

     this.state = { 
      data: [] 
     }; 
    } 

    componentWillMount() { 
     $.ajax({ 
      url: './app/data/namegame-data.json', 
      dataType: 'json', 
      success: function(data) { 
      this.setState({data: data}); 
      }.bind(this), 
      error: function(xhr, status, err) { 
      console.error('#GET Error', status, err.toString()); 
      }.bind(this) 
     }); 
    } 

    shuffleArray(array) { 
     let i = array.length - 1; 
     for (; i > 0; i--) { 
     const j = Math.floor(Math.random() * (i + 1)); 
     const temp = array[i]; 
     array[i] = array[j]; 
     array[j] = temp; 
     } 
     return array; 
    } 

    selectImages() { 
     const shuffledImages = this.shuffleArray(this.state.data); 
     return (
      shuffledImages.map((data, idx) => { 
      for (let i = 0; i < this.numImages; i++) { 
       return <Image key={idx} name={this.state.data.name} src={this.state.data.src} />; 
      } 
      }) 
    ); 
    } 

    render() { 
     return (
      <div> 
       {this.selectImages()}; 
      </div> 
     ) 
    } 
} 
0

我赶紧在00:45改变我们的代码:d,但尝试这样的事情,explenation我在其他的答案。 GL!

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Image } from './Image'; 

export class ImageContainer extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      data: [], 
      numImages: 5 
     }; 
    } 

    componentWillMount() { 
     $.ajax({ 
      url: './app/data/namegame-data.json', 
      dataType: 'json', 
      type: 'get', 
      success: function(data) { 
      this.setState({data: JSON.parse(data) }); 
      }.bind(this), 
      error: function(xhr, status, err) { 
      console.error('#GET Error', status, err.toString()); 
      }.bind(this) 
     }); 
    } 

    randomPickFromArray() { 
     // * as asked: " Attempting to turn a JSON file into an array, then randomly selecting 5 items from it. " 

     // lets not shuffle, and just random pick 5 items from array, 
     const { data, numImages } = this.state; 
     const arr = []; 
     for (let i = 0; i < numImages; i++) { 
     arr.push(data[Math.floor(Math.random() * data.length)]); 
     } 
     return arr; 
    } 

    selectImages() { 
     const shuffledImages = this.randomPickFromArray(); 
     return shuffledImages.map((item, idx) => <Image key={idx} name={item.name} src={item.src} />); 
    } 

    render() { 
     return (
      <div> 
       {this.selectImages()}; 
      </div> 
     ) 
    } 
}