【问题标题】:Convert Class component to functional using hooks使用钩子将类组件转换为函数式
【发布时间】:2021-05-31 02:49:18
【问题描述】:

我正在尝试使用钩子将其转换为功能组件,但没有运气。我该怎么做? (新的钩子)。我试图遵循文档,但我一定不理解它。这应该以相同的方式工作,但使用钩子的功能组件。

import React, { Component } from "react";
    const texts = [
  ['Text 1', 'blah', 'sdklfj'],
  ['Text 2', 'blah', 'sdklfj'],
  ['Text 3', 'blah', 'sdklfj'],
  ['Text 4', 'blah', 'sdklfj'],
];


export default class Testing extends Component {
  constructor(props) {
    super(props);
    this.state = {
      clickedText: [],
    };
  }

  handleClick = (i) => {
    this.setState({ clickedText: texts[i] });
  };

  render() {
    const { clickedText } = this.state;
    return (
      <div>
        {texts.map((text, i) => (
          <button key={i} onClick={() => this.handleClick(i)}>
            Click me {i + 1}
          </button>
        ))}
        {clickedText.length > 0 && <p>I clicked on button with text:</p>}
        <ul>
          {clickedText.map((t, i) => (
            <li key={`text-${i}`}>{t}</li>
          ))}
        </ul>
      </div>
    );
  }
}

【问题讨论】:

    标签: reactjs react-hooks components


    【解决方案1】:
    import React, { useState } from 'react';
    
    const texts = [
        ['Text 1', 'blah', 'sdklfj'],
        ['Text 2', 'blah', 'sdklfj'],
        ['Text 3', 'blah', 'sdklfj'],
        ['Text 4', 'blah', 'sdklfj'],
    ];
    
    const Testing = (props) => {
        // useState is the function component equivalent of the inherited 'setState'
        const [clickedText, setClickedText] = useState([]);
    
        const handleClick = (i) => {
            setClickedText(texts[i]);
        };
    
        return (
            <div>
                {texts.map((text, i) => (
                    <button key={i} onClick={() => handleClick(i)}>
                        Click me {i + 1}
                    </button>
                ))}
                {clickedText.length > 0 && <p>I clicked on button with text:</p>}
                <ul>
                    {clickedText.map((t, i) => (
                        <li key={`text-${i}`}>{t}</li>
                    ))}
                </ul>
            </div>
        );
    };
    
    export default Testing;
    

    【讨论】:

    • 点击Cannot read property 'handleClick' of undefined无效
    • 抱歉,忘记const
    • 谢谢,这是有道理的,有时我必须自己重复几次。我知道我自己搞砸了。
    • onClick={() =&gt; this.handleClick(i)} 是错误的。删除this
    【解决方案2】:

    首先,您需要将类组件中的当前状态替换为功能组件的useState 特性。另请阅读关于在功能组件中使用状态的 docsandbox

    import React, { useState } from "react";
    
    const texts = [
      ["Text 1", "blah", "sdklfj"],
      ["Text 2", "blah", "sdklfj"],
      ["Text 3", "blah", "sdklfj"],
      ["Text 4", "blah", "sdklfj"]
    ];
    
    const Testing = (props) => {
      const [clickedText, setClickedText] = useState([]);
    
      const handleClick = (i) => {
        setClickedText(texts[i]);
      };
    
      return (
        <div>
          {texts.map((text, i) => (
            <button key={i} onClick={() => handleClick(i)}>
              Click me {i + 1}
            </button>
          ))}
          {clickedText.length > 0 && <p>I clicked on button with text:</p>}
          <ul>
            {clickedText.map((t, i) => (
              <li key={`text-${i}`}>{t}</li>
            ))}
          </ul>
        </div>
      );
    };
    
    export default Testing;
    

    【讨论】:

    • 谢谢,这是有道理的,有时我必须自己重复几次。我知道我自己搞砸了。
    • 这似乎比基于类的组件容易得多,但我喜欢同时学习。
    • 是的,它比基于类的复杂得多
    【解决方案3】:

    学习如何使用useState、useRef、useEffect。在您的示例中,您不需要 useEffect 但您将需要它。

    这是带有钩子的代码:

    import { useRef, useState } from "react";
    import "./styles.css";
    
    export default function App() {
       const [clickedText, setClickedText] = useState([]);
       const texts = useRef([
         ["Text 1", "blah", "sdklfj"],
         ["Text 2", "blah", "sdklfj"],
         ["Text 3", "blah", "sdklfj"],
         ["Text 4", "blah", "sdklfj"]
    ]);
    
    const handleClick = (i) => {
       setClickedText(texts.current[i]);
     };
    
     return (
        <div>
          {texts.current.map((text, i) => (
             <button key={i} onClick={() => handleClick(i)}>
                 Click me {i + 1}
             </button>
          ))}
          {clickedText.length > 0 && <p>I clicked on button with text:</p>}
          <ul>
              {clickedText.map((t, i) => (
                 <li key={`text-${i}`}>{t}</li>
              ))}
          </ul>
          </div>
     );
     }
    

    https://codesandbox.io/s/hidden-waterfall-s0t0m?file=/src/App.js

    【讨论】:

    • 谢谢,这是有道理的,有时我必须自己重复几次。我知道我自己搞砸了。
    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
    • @Chris 添加了内联代码。谢谢你的警告。
    猜你喜欢
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2020-09-17
    相关资源
    最近更新 更多