我想根据其在 React 组件内的初始宽度或高度加载动态格式化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
)
}
或
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" />
)
}
我想你对new Image
和onload
有一些误解.
第一个代码,要呈现的内容应该是"HTML 元素"(至少看起来像),但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} />
)
}
第一个不起作用,因为 render() 方法不应该返回 DOM 元素。我想你误解了 React 应该如何工作。
你在 React 中使用的标签不是 html,也不是 html DOM 元素。标签是JSX,这是Babel理解的语法糖,并在生成捆绑javascript文件时转换为常规的javascript。
所以下面的JSX:
<h1>hello</h1>
变成以下 JavaScript:
React.createElement(
"h1",
null,
"hello"
);
这就是为什么你必须使用
import React from 'react';
即使它看起来不像你在任何地方使用它。
实际上,您实际上是在使用它,因为这就是JSX所代表的。
无论如何,回到上面的代码,createElement 的第一个参数"h1"告诉 React 您希望类型为"h1",第三个参数是"hello",因为这就是您希望孩子成为的样子。
因此,如果您的 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 会在它认为合适的时候处理实际的"做",以及它认为合适的方式。
我谈到的模板结构,例如:
React.createElement(
"h1",
null,
"hello"
);
很特别。
任何 React 组件的 return() 方法都必须返回该类型的对象。它不能返回任何其他内容,并且绝对不能返回 DOM 对象。
你的第二个代码块几乎可以工作,尽管它仍然不是在 React 中做这样的事情的首选方式。但是,如果您真的想这样做,则需要解决一些问题。
首先,"onload"属性应该拼写为"onLoad"。另外,您需要使用
this.formatImage
确保你不使用括号,否则代码将在 React 将你的图像放在页面上之前实际运行。现在它为什么要这样做?
因为 Babel 会改变你的 JSX:
<img onload={formatImg()} id="some-img" />
进入这个:
React.createElement(
"img",
{ onload: formatImg(), id: "some-img" }
);
请注意,在您的代码中,"formatImg"函数实际上在作为参数传递到 React.createElement之前就运行了。(在创建模板之前,绝对在将其放到页面上之前。