简体   繁体   English

如何在几乎没有变化的情况下重用 React 组件

[英]How can I reuse React components with little variation

I want to recreate something similar to this using React.我想使用 React 重新创建类似的东西。 I also want to use 1 Player component for 2 players.我还想为 2 个玩家使用 1 Player 组件。 Since there is an increment and decrement button for both players, how can I let App.js distinguish the difference between the 2 Players?既然两个玩家都有递增和递减按钮,那么我如何让 App.js 区分两个玩家之间的区别? I understand I can probably pass it in as an argument but where do I set that?我知道我可以将它作为参数传递,但我在哪里设置它?

This is what I have for App.js and it's working for, obviously, a single player:这就是我对 App.js 所拥有的,显然它适用于单个玩家:

constructor(props) {
    super(props);
    this.state = {
      player1: 20,
      player2: 20
    };
  }

  increment = () => {
      this.setState({
        player1: this.state.player1 + 1,
        player2: this.state.player2
  };

You can pass an argument to your increment function indicating which player it is您可以将参数传递给增量函数,指示它是哪个玩家

 increment = (p) => {
      this.setState({
        [p]: this.state[p] + 1,
  };

and pass a handler to Player instance accordingly:并相应地将处理程序传递给 Player 实例:


return (
   <Player increment={() => { this.increment('player1') }} />
   <Player increment={() => { this.increment('player2') }} />
)

in your Player component you would do something like在您的 Player 组件中,您会执行类似的操作


const Player = (props) => {
    return (
      // I assume you would have some button somewhere
      <button onClick={() => { props.increment() }}
    )

}

You just need to make your state changing method take some arguments.你只需要让你的状态改变方法接受一些参数。 Taking player and amount means that you decide what player and how much to change the life totals when you call this method.获取playeramount意味着您在调用此方法时决定要更改哪个玩家以及多少总生命。

updateLife = (player, amount) => {
  this.setState({
    [player]: this.state[player] + amount,
  })
}

Then call that when you render your common LifeTracker component that tracks just one life total, and provides a callback when someone takes an action to change that life total.然后在渲染仅跟踪一个总生命值的公共LifeTracker组件时调用它,并在有人采取操作更改该总生命值时提供回调。 All you have to call your updateLife method in the callback with the right arguments.您只需使用正确的参数在回调中调用updateLife方法即可。

<LifeTracker
  life={this.state.player1}
  onChange={(amount) => this.updateLife('player1', amount) }
/>
<LifeTracker
  life={this.state.player2}
  onChange={(amount) => this.updateLife('player2', amount) }
/>

Lastly, inside your LifeTracker component, just use the props as they are unique to just that life tracker.最后,在你的 LifeTracker 组件中,只需使用道具,因为它们是生命追踪器独有的。

function LifeTracker({life, onChange}) {
  return <div>
    <div>{life}</div>
    <div onClick={() => onChange(1)}>up</div>
    <div onClick={() => onChange(-1)}>down</div>
  </div>
}

Some pseudo code for you -一些伪代码给你 -

const Player = ({ increment, player }) => {
  const onClick = () => increment(player.id);

  return (
    <div>
      {player.name}
      <button onClick={onClick}>Increment</button>
    </div>
  );
}

const App = () => {
  const [players, setPlayers] = useState([{ name: 'Player 1', id: 1, points: 0 }, { name: 'Player 2', id: 2, points: 0 }];

  const increment = (playerId) => {
    const newPlayers = players.map(player => {
      if (player.id === playerId) {
        player.points = player.points + 1;
      }

      return player;
    });

    setPlayers(newPlayers);
  };

  return players.map(player => <Player increment={increment} player={player} />);
}

So you restructure your state a little bit so each player is an object in an array.所以你稍微重组你的状态,让每个玩家都是数组中的一个对象。 Then you pass in the player's id when you want to increment their points in the parent component.然后,当您想在父组件中增加玩家的点数时,传入玩家的 id。 Let me know if you have any further questions.如果您有任何其他问题,请告诉我。

Here's what I suggest: you can create two different increment functions: one for your first player, and one - for a second one.这是我的建议:您可以创建两个不同的increment函数:一个用于您的第一个玩家,另一个用于第二个。

constructor(props) {
    super(props);
    this.state = {
      player1: 20,
      player2: 20
    };
  }

  incrementFirstPlayer = () => {
      this.setState({
        player1: this.state.player1 +1 )}
  };

  incrementSecondPlayer = () => {
      this.setState({
        player2: this.state.player2 +1 )}
  };

This also can be your parent component.这也可以是您的父组件。 You can then create two children (player) components and pass props (number and increment callback) to them.然后,您可以创建两个子(播放器)组件并将道具(数字和增量回调)传递给它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM