如何使用相同的函数转换不同的元素?我可以使用类似this.target
之类的东西吗?
这里有一个示例,我想在单击“移动框”按钮时转换Box组件。但是现在无论我单击哪个按钮,只有第一个Box都会被转换...
const handleChangePos = () => {
let box = document.getElementById("box");
box.style.transform = `translateY(-20px)`;
};
const n = 4;
function App() {
return (
<div className="App">
<h1>Hero</h1>
<HeroBox>
<Box id="box" />
<button onClick={handleChangePos}>Move Box</button>
</HeroBox>
<h2>Sub Hero</h2>
<SubHeroContainer>
{[...Array(n)].map((e, i) => (
<SubHeroBox key={i}>
<Box2 id="box" />
<button onClick={handleChangePos}>Move Box</button>
</SubHeroBox>
))}
</SubHeroContainer>
</div>
);}
实时示例: https://codesandbox.io/s/6vxqlo06v3
我想要的理想结果是单击按钮,然后将其相应的Box转换,而其他Box都不会受到影响。
答案 0 :(得分:1)
您需要创建一个包含所需功能的新组件。使用React,您永远不需要调用document.getElementById
我已经编辑了您的示例,以创建一个新组件,该组件将其偏移量存储在组件状态中。这可以解决子框的问题,但是您还需要找到一种使其可扩展到主英雄框的方法。
https://codesandbox.io/s/3vn642j63m
以下是链接死亡的相关组件:
class Moveable extends React.Component {
constructor() {
super();
this.state = { offset: 0 };
this.move = this.move.bind(this);
}
move() {
if (this.state.offset === 0) {
this.setState({ offset: -20 });
} else {
this.setState({ offset: 0 });
}
}
render() {
return [
<Box2 id="box" style={{transform: `translateY(${this.state.offset}px)`}} />,
<button onClick={this.move}>Move Box</button>
];
}
}
答案 1 :(得分:1)
您可以通过多种方式轻松解决此问题,但首先,您不应具有具有相同ID的多个元素。由于您已经有了id="Box"
作为标题,我建议使用索引生成其余的内容:
<SubHeroContainer>
{[...Array(n)].map((e, i) => (
<SubHeroBox key={i}>
<Box2 id={`box-${i}`} />
<button onClick={() => handleChangePos(i)}>Move Box</button>
</SubHeroBox>
))}
</SubHeroContainer>
然后可以修改handleChangePos
以接受参数(索引)并找到给定的元素:
const handleChangePos = (index) => {
let box = document.getElementById(index ? `box-${index}` : "box");
box.style.transform = `translateY(-20px)`;
};
为避免传递索引,您还可以在单击按钮时通过按钮传递的事件中使用event.target.name
,并像<button onClick={handleChangePos} name={i} >Move Box</button>
那样声明按钮,但两者基本相同。
我还建议不要使用ID,而是维护refs
的列表,并根据索引对其进行修改。您可以在这里阅读有关裁判的更多信息:https://reactjs.org/docs/refs-and-the-dom.html