如何在React中为不同的元素使用相同的功能?

时间:2018-09-10 05:35:00

标签: javascript reactjs function

如何使用相同的函数转换不同的元素?我可以使用类似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都不会受到影响。

2 个答案:

答案 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