Javascript ReactJS在接收要渲染的数据之前调用render方法

Javascript ReactJS在接收要渲染的数据之前调用render方法,javascript,reactjs,Javascript,Reactjs,加载主组件时,我向API发送GET请求,以获取名为“ship_name”的字段中具有特定值的所有对象,这意味着可能会有更多的“构建”,因此将有更多的对象需要渲染。加载主组件后,我在同一个文件中创建了第二个组件,称为“Builds”。作为道具,我向这个组件this.state.builds发送一个对象数组 更好的解释: 用户在搜索栏中插入“ship_name” API查找所有具有该“ship_名称”的生成 所有构建都将发送到子组件 使用“齿轮”(齿轮名称)API查找文件名并将其发送回 !!在链接到

加载主组件时,我向API发送GET请求,以获取名为
“ship_name”
的字段中具有特定值的所有对象,这意味着可能会有更多的“构建”,因此将有更多的对象需要渲染。加载主组件后,我在同一个文件中创建了第二个组件,称为“Builds”。作为道具,我向这个组件this.state.builds发送一个对象数组

更好的解释:

  • 用户在搜索栏中插入“ship_name”
  • API查找所有具有该“ship_名称”的生成
  • 所有构建都将发送到子组件
  • 使用“齿轮”(齿轮名称)API查找文件名并将其发送回
  • !!在链接到达之前作出反应
  • 
    
    “构建”的结构是这样的

    [
    {
    “齿轮”:[
    “三重410mm(10年型原型)”,
    “三重155mm(第三年型)”,
    “双40毫米Bofors STAAG Mk II”,
    “高性能火控雷达”,
    “1型穿甲弹”
    ],
    “珍品”:[
    “o”,
    “o”,
    “o”,
    “o”,
    “o”
    ],
    “_id”:“5eac7b450e64096b082f4c43”,
    “船名”:“Gasconge”,
    “pv”:“e”
    },
    {
    “齿轮”:[
    “三重410mm(10年型原型)”,
    “三重155mm(第三年型)”,
    “双40毫米Bofors STAAG Mk II”,
    “高性能火控雷达”,
    “1型穿甲弹”
    ],
    “珍品”:[
    “o”,
    “o”,
    “o”,
    “o”,
    “o”
    ],
    “_id”:“5f131d6e2e3f16ef3de48e4f”,
    “船名”:“Gasconge”,
    “pv”:“e”
    }
    ]
    
    到目前为止一切正常

    render(){
    返回(
    this.props.builds.map((build)=>(
    {build.gears[0]}
    {build.gears[1]}
    {build.gears[2]}
    {build.gears[3]}
    {build.gears[4]}
    ))
    )
    }
    /*------------------------------*/
    getGearData(齿轮名称){
    let requestString=encodeURI('http://localhost:5000/gears/one?q=“+gear_名称)
    让数据;
    获取(请求字符串)
    。然后(res=>{
    console.log(res.data[0].image\u链接)
    data=res.data[0]。图像链接
    })
    返回数据
    /*什么*/
    }
    
    这里发生的事情是,当我渲染时,同时我尝试获取图像的URL。GET方法起作用,实际上console.log打印文件的实际名称

    32200.png gear.component.js:76 
    26600.png gear.component.js:76 
    1260.png gear.component.js:76 
    600.png gear.component.js:76 
    34180.png gear.component.js:76 
    
    但是在SRC上,结果是“/img/gears/undefined”。有一件事我不明白,为什么所有的结果都被打印了两次,但这不是什么大问题,因为最终这些东西只被正确地渲染了一次

    我尝试过使用很多方法、陈述、承诺(即使我还没有真正理解它们是如何工作的),这是我第一次真正陷入这样的困境。事实上,主组件使用“ship_name”来获取“ship_图标”和“派系_图标”的文件名,这没有问题,可能是因为我使用了那里的状态

    这里有一个关于它现在的样子的想法

    这里有一个关于它应该是什么样子的想法


    我曾经使用php和SQL完成过这个个人项目,现在我尝试使用React和MongoDB来完成它。

    这是因为
    Axios.get
    是一个异步函数,所以在设置变量数据之前返回变量

    我还要说,这是一个糟糕的设计,最好将获取异步数据和渲染的关注点分开,例如

    async componentDidMount() {
        const containerToRender = (<></>);
    
        await Promise.all(
          this.props.builds.map(async (build) => {
            const container = <container ... key={build._id} />
            await Promise.all(build.gears.map(async (gear, i) => {
              container.children.push(<img src={"/img/gears/" + await this.getGearData(gear)} className={`${build.rarities[i]} gI g${i + 1}"} key={`img.${gear}.${i} />)
              container.children.push(<div className={`t t${i + 1}`} key={`div.${gear}.${i}>{gear}</div>)
            })
            containerToRender.children.push(container)
          })
    
        this.setState({ containerToRender });
    }
    
    getGearData(gear_name) {
      const requestString = encodeURI('http://localhost:5000/gears/one?q=' + gear_name)
    
      return Axios.get(requestString).then(res => res.data[0].image_link)
    }
    
    render() {
        return (this.state.containerToRender);
    }
    
    异步组件didmount(){ 常量containerToRender=(); 等待承诺( this.props.builds.map(异步(构建)=>{ 常量容器= 等待承诺.all(build.gears.map)(异步(gear,i)=>{ container.children.push() container.children.push({gear}) }) containerToRender.children.push(容器) }) this.setState({containerToRender}); } getGearData(齿轮名称){ const requestString=encodeURI('http://localhost:5000/gears/one?q=“+gear_名称) 返回Axios.get(requestString).then(res=>res.data[0].image\u链接) } render(){ 返回(this.state.containerToRender); } 注意:您应该在检索和/或设置构建的过程中调用获取图像URL。首先,此数据结构是设计不佳的标志;现在,这意味着:
  • React是一个反应性库。它只对正在监视的数据的更改作出反应

  • 您不能混合使用异步和同步函数,而期望一切都等待

  • 当您调用
    getGearData(gear\u name)
    时,这里将按照发生的顺序大致列出发生的情况

  • 使用变量
    gear\u name
  • 声明一个可修改变量
    requestString
    ,并将其设置为
    encodeURI('http://localhost:5000/gears/one?q=“+gear_name)
    (侧注,这应该是
    const
    ,因为它没有被修改
  • 声明了一个可修改的变量
    data
  • 启动异步请求以从服务器检索数据
  • 数据的当前值的引用将返回给调用者
  • 反应渲染
  • 你的请求完成了
  • 局部变量
    数据
    在功能范围内设置
  • 您必须等待异步操作 有很多方法可以做到这一点。下面是一个使用占位符图像的示例

    const占位符=”https://link.to/placehold