根据React

时间:2018-01-24 01:00:38

标签: javascript html css image reactjs

我希望根据React组件内部的初始宽度或高度onload动态格式化img的宽度或高度,但下面的两个都不起作用,第一个没有完全渲染img而第二个无法找到some-img。我想做什么?

  const img = new Image()
  img.onload = () => {
    const height = img.height
    const width = img.width

    if (width < height) {
      img.style.width = '105px'
    } else {
      img.style.height = '105px'
    }
  }
  img.src = avatar.url

  render () {
    return (
      img
    )
  }

OR

  const formatImg = () => {
    const height = img.height
    const width = img.width

    if (width < height) {
      document.getElementById('some-img').style.width = '105px'
    } else {
      document.getElementById('some-img').style.height = '105px'
    }

  }

  render () {
    return (
      <img src={avatar.url} onload={formatImg()} id="some-img" />
    )
  }

2 个答案:

答案 0 :(得分:0)

我认为您对new Imageonload有一些误解。

第一个代码,要呈现的内容应该是&#34; HTML元素&#34;(至少看起来像),但img = new Image不是。那你用变量img做什么当然不行。

第二个代码onload = {formatImg()}表示分配给onload prop的formatImg()的返回值。你应该像这样编码:onload = {formatImg}

最后一件事,如果我使用React,我永远不会尝试直接操作DOM元素。相反,尽可能使用setState以便render循环运行。

稍微修改你的第二个:

const formatImg = () => {
  const height = img.height
  const width = img.width

  if (width < height) {
    this.setState({width: '105px', height: height + 'px'})
   // document.getElementById('some-img').style.width = '105px'
  } else {
    this.setState({width: width + 'px', height: '105px'})
   // document.getElementById('some-img').style.height = '105px'
  }
}

render () {
  const { width, height } = this.state;
  return (
    <img src={avatar.url} onload={this.formatImg} style={{width, height} />
  )
}

答案 1 :(得分:0)

第一个不起作用,因为render()方法不应该返回DOM元素。我想你误解了React应该如何工作。
你在React中使用的标签不是html,也不是html DOM元素。标签是JSX,它是Babel理解的语法糖,并在生成bundle javascript文件时变成常规javascript。
所以下面的JSX:

<h1>hello</h1>

转到以下javascript:

React.createElement(
  "h1",
  null,
  "hello"
);

这就是你必须使用

的原因
import React from 'react';

即使它看起来不像你在任何地方使用它。
实际上,你实际上 使用它,因为那是什么JSX代表。

无论如何,回到上面的代码,第一个参数&#34; h1&#34; for createElement告诉React你希望类型为&#34; h1&#34;,第三个参数是&#34; hello&#34;因为这就是你想要的孩子。

所以如果你的JSX是:

<div><img></img></div>

然后编译的javascript是:

React.createElement(
  "div",
  null,
  React.createElement("img", null)
);

如果您想玩JSX,可以使用: https://babeljs.io/repl/

现在是重要的一部分。当您使用React.createElement时,您创建DOM元素。您甚至没有实例化React组件(如果您定义了自己的组件)。

你所做的就是给React一个模板结构,告诉React你打算做什么。并且React将处​​理实际的&#34;做&#34;当它看起来合适时,以及它认为合适的方式。

我谈过的模板结构,例如:

React.createElement(
  "h1",
  null,
  "hello"
);

很特别。
任何React组件的return()方法必须返回该类型的对象。它不能返回任何其他内容,它肯定无法返回DOM对象。

你的第二个代码块将几乎工作,尽管它仍然不是在React中做这样的事情的首选方式。但如果你真的想这样做,你需要解决一些问题。

首先,&#34; onload&#34;财产应该拼写&#34; onLoad&#34;。此外,您需要使用

this.formatImage

确保您不使用括号,否则代码将在React甚至将您的图像放在页面上之前实际运行。现在为什么这样做?
因为Babel会改变你的JSX:

<img onload={formatImg()} id="some-img" />

进入这个:

React.createElement(
     "img", 
     { onload: formatImg(), id: "some-img" }
);

请注意代码中的&#34; formatImg&#34;函数实际运行之前它甚至作为参数传递给React.createElement。 (甚至在创建模板之前,肯定在它被放到页面之前。)