将组件重构为带有条件样式的FunctionComponent(使用onMouseEnter/Leave)。

huangapple go评论73阅读模式
英文:

Refactor Component to FunctionComponent with conditional style (onMouseEnter/Leave)

问题

我进入了React世界并完成了教程。我们最终得到了一个FunctionComponent:

function Square(props) {
  return (
    <button className="square" onClick={props.onClick}>
      {props.value}
    </button>
  );
}

我的结果略有不同,我试图解构props以将组件特定的props与DOM属性分离:

function Square({value, ...domProps}) {
  return (
    <button
      className="square"
      {...domProps}
    >
      {value}
    </button>
  );
}

父组件是:

class Board extends React.PureComponent {
  renderSquare(i) {
    return (
      <Square
        value={this.props.squares[i]}
        onClick={() => this.props.onClick(i)}
      />
    );
  }

  render() {
    return (
      <div>
        <div className="board-row">
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        </div>
        <div className="board-row">
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        </div>
        <div className="board-row">
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        </div>
      </div>
    );
  }
}

我想要做的是在鼠标悬停在Square元素上时添加背景颜色。因此,我决定添加mouseEnter和mouseLeave的处理程序,但不知道接下来该怎么做。

所以我将我的FunctionComponent更改为了Component:

class Square extends React.PureComponent{ 
  constructor(props) {
    super(props);
    const { value, ...platformProps } = props;
    this.state = {
      isHovered: false,
      platformProps: platformProps,
    };
  }

  render() {
    return (
      <button
        className="square"
        {...this.state.platformProps}
        onMouseEnter={() => this.setState({isHovered: true})}
        onMouseLeave={() => this.setState({isHovered: false})}
        style={this.state.isHovered ? { backgroundColor: Color('indigo').lighten(0.5) } : {}}
      >
        {this.props.value}
      </button>
    );
  }
}

这个做法虽然有效,但不够优雅,而且我不想在Square组件中处理条件样式。我只想Square成为一个我可以重复使用的低级组件。我错过了什么?

英文:

So I'm entering into React world and completed the tutorial. We end up with a FunctionComponent :

function Square(props) {
  return (
    &lt;button className=&quot;square&quot; onClick={props.onClick}&gt;
      {props.value}
    &lt;/button&gt;
  );
}

My result is slightly different, I tried to deconstruct props to separate component-specific props from DOM attributes :

function Square({value, ...domProps}) {
  return (
    &lt;button
      className=&quot;square&quot;
      {...domProps}
    &gt;
      {value}
    &lt;/button&gt;
  );
}

The parent component is :

class Board extends React.PureComponent {
  renderSquare(i) {
    return (
      &lt;Square
        value = {this.props.squares[i]}
        onClick = {() =&gt; this.props.onClick(i)}
      /&gt;
    );
  }

  render() {
    return (
      &lt;div&gt;
        &lt;div className=&quot;board-row&quot;&gt;
          {this.renderSquare(0)}
          {this.renderSquare(1)}
          {this.renderSquare(2)}
        &lt;/div&gt;
        &lt;div className=&quot;board-row&quot;&gt;
          {this.renderSquare(3)}
          {this.renderSquare(4)}
          {this.renderSquare(5)}
        &lt;/div&gt;
        &lt;div className=&quot;board-row&quot;&gt;
          {this.renderSquare(6)}
          {this.renderSquare(7)}
          {this.renderSquare(8)}
        &lt;/div&gt;
      &lt;/div&gt;
    );
  }
}

What I wanted to do is add a background-color on Square element when I hover it. So I decided to add handlers for mouseEnter and mouseLeave, but I had no idea what to do then.

So I changed my FunctionComponent to a Component :

class Square extends React.PureComponent{ 
  constructor(props) {
    super(props);
    const { value, ...platformProps } = props;
    this.state = {
      isHovered: false,
      platformProps: platformProps,
    };
  }

  render() {
    return (
      &lt;button
        className=&quot;square&quot;
        {...this.state.platformProps}
        onMouseEnter={() =&gt; this.setState({isHovered: true})}
        onMouseLeave={() =&gt; this.setState({isHovered: false})}
        style={this.state.isHovered ? { backgroundColor: Color(&#39;indigo&#39;).lighten(0.5) } : {}}
      &gt;
        {this.props.value}
      &lt;/button&gt;
    );
  }
}

This is working but it's ugly and I didn't want to handle conditional styling into Square component. I only wanted Square to be dumb low-level component that I can reuse. What am I missing ?

Here is the sandbox project

答案1

得分: 1

以下是您要翻译的内容:

"这是使用 useState 钩子的等效函数组件。

const Square = ({value, ...platformProps}) =&gt; {
  const [isHovered, setHovered] = useState();

  return (
    &lt;button
      className=&quot;square&quot;
      {...platformProps}
      onMouseEnter={() =&gt; setHovered(true)}
      onMouseLeave={() =&gt; setHovered(false)}
      style={
        isHovered
          ? { backgroundColor: Color(&quot;indigo&quot;).lighten(0.5) }
          : {}
      }
    &gt;
      {value}
    &lt;/button&gt;
  );
};
```"

<details>
<summary>英文:</summary>

That&#39;s the equivalent function component using `useState` hook.

```jsx
const Square = ({value, ...platformProps}) =&gt; {
  const [isHovered, setHovered] = useState();

  return (
    &lt;button
      className=&quot;square&quot;
      {...platformProps}
      onMouseEnter={() =&gt; setHovered(true)}
      onMouseLeave={() =&gt; setHovered(false)}
      style={
        isHovered
          ? { backgroundColor: Color(&quot;indigo&quot;).lighten(0.5) }
          : {}
      }
    &gt;
      {value}
    &lt;/button&gt;
  );
};

huangapple
  • 本文由 发表于 2020年1月3日 23:06:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/59580889.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定