首页 > 解决方案 > 我需要下面的代码写成 React Hooks。可以这样写吗?

问题描述

我主要在我当前的应用程序中使用反应钩子。我需要下面的代码表示为反应钩子,没有 this.state 和 this.props。我当前的应用程序完全表示为 React Hooks。如果你仔细看的话,下面的代码就是通过点击一个按钮来写出 SQL 查询代码。我在当前的应用程序中需要该功能,但我不知道如何在我的应用程序中吸收它。有任何想法吗?

import React from 'react';
import { Row, Col, Tabs, Spin, Card, Alert, Tooltip, Icon, Button } from 'antd';
import cubejs from '@cubejs-client/core';
import { QueryRenderer } from '@cubejs-client/react';
import sqlFormatter from "sql-formatter";
import JSONPretty from 'react-json-pretty';
import Prism from "prismjs";
import "./css/prism.css";

const HACKER_NEWS_DATASET_API_KEY = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpIjozODU5NH0.5wEbQo-VG2DEjR2nBpRpoJeIcE_oJqnrm78yUo9lasw'

class PrismCode extends React.Component {
  componentDidMount() {
    Prism.highlightAll();
  }

  componentDidUpdate() {
    Prism.highlightAll();
  }

  render() {
    return (
      <pre>
        <code className='language-javascript'>
          { this.props.code }
        </code>
      </pre>
    )
  }
}

const tabList = [{
  key: 'code',
  tab: 'Code'
}, {
  key: 'sqlQuery',
  tab: 'Generated SQL'
}, {
  key: 'response',
  tab: 'Response'
}];

class CodeExample extends React.Component {
  constructor(props) {
    super(props);

    this.state = { activeTabKey: 'code' };
  }

  onTabChange(key) {
    this.setState({ activeTabKey: key });
  }

  render() {
    const { codeExample, resultSet, sqlQuery } = this.props;
    const contentList = {
      code: <PrismCode code={codeExample} />,
      response: <PrismCode code={JSON.stringify(resultSet, null, 2)} />,
      sqlQuery: <PrismCode code={sqlQuery && sqlFormatter.format(sqlQuery.sql())} />
    };

    return (<Card
      type="inner"
      tabList={tabList}
      activeTabKey={this.state.activeTabKey}
      onTabChange={(key) => { this.onTabChange(key, 'key'); }}
    >
      { contentList[this.state.activeTabKey] }
    </Card>);
  }
}

const Loader = () => (
  <div style={{textAlign: 'center', marginTop: "50px" }}>
    <Spin size="large" />
  </div>
)

const TabPane = Tabs.TabPane;
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = { showCode: false };
  }

  render() {
    const { query, codeExample, render, title } = this.props;
    return (
      <QueryRenderer
        query={query}
        cubejsApi={cubejs(HACKER_NEWS_DATASET_API_KEY)}
        loadSql
        render={ ({ resultSet, sqlQuery, error, loadingState }) => {
          if (error) {
            return <Alert
              message="Error occured while loading your query"
              description={error.message}
              type="error"
            />
          }

          if (resultSet && !loadingState.isLoading) {
            return (<Card
              title={title || "Example"}
              extra={<Button
                onClick={() => this.setState({ showCode: !this.state.showCode })}
                icon="code"
                size="small"
                type={this.state.showCode ? 'primary' : 'default'}
              >{this.state.showCode ? 'Hide Code' : 'Show Code'}</Button>}
            >
              {render({ resultSet, error })}
              {this.state.showCode && <CodeExample resultSet={resultSet} codeExample={codeExample} sqlQuery={sqlQuery}/>}
            </Card>);
          }

          return <Loader />
        }}
      />
    );
  }
};

export default Example; 

标签: javascriptreactjsreact-native

解决方案


将类转换为功能组件非常容易。

记住这些步骤:

  1. =>常量
  // Class
  export class Example

  // FC
  export const Example
  1. 组件生命周期=>使用效果
  // Class lifecycle
  componentDidMount() { 
      // logic here 
  } 
  // FC
  useEffect(() => { 
      // logic here 
  })
  1. 渲染=>返回
  // Class
  render () { 
    return (<Component/>) 
  } 

  // FC
  return (<Component />)`
  1. 构造函数=> useState
  // Class
  constructor(props) { 
    this.state.val = props.val 
  }

  // FC
  const [val, setVal] = useState(props.val)
  1. setState =>来自 useState 的第二个参数
  // Class
  constructor() {
    this.state.val = val  // constructor
  }
  this.setState({ val }) // class

  // FC
  const[val, setVal] = useState(null)
  setVal("someVal")

TLDR:解决方案

import React, { useEffect, useState } from "react"
import { Tabs, Spin, Card, Alert, Button } from "antd"
import cubejs from "@cubejs-client/core"
import { QueryRenderer } from "@cubejs-client/react"
import sqlFormatter from "sql-formatter"
import Prism from "prismjs"
import "./css/prism.css"

const HACKER_NEWS_DATASET_API_KEY =
  "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpIjozODU5NH0.5wEbQo-VG2DEjR2nBpRpoJeIcE_oJqnrm78yUo9lasw"

const PrismCode: React.FC = ({ code }) => {
  useEffect(() => {
    Prism.highlightAll()
  })

  return (
    <pre>
      <code className="language-javascript">{code}</code>
    </pre>
  )
}


const TabList = [
  {
    key: "code",
    tab: "Code",
  },
  {
    key: "sqlQuery",
    tab: "Generated SQL",
  },
  {
    key: "response",
    tab: "Response",
  },
]


const CodeExample: React.FC = ( { codeExample, resultSet, sqlQuery } ) => {
  const [activeTabKey, setActiveTab] = useState("code")
  
  const onTabChange = (key) => setActiveTab(key)
  
  const contentList = {
    code: <PrismCode code={codeExample} />,
    response: <PrismCode code={JSON.stringify(resultSet, null, 2)} />,
    sqlQuery: (
      <PrismCode code={sqlQuery && sqlFormatter.format(sqlQuery.sql())} />
    ),
  }

  return (
    <Card
      type="inner"
      tabList={TabList}
      activeTabKey={activeTabKey}
      onTabChange={(key) => {
        onTabChange(key)
      }}
    >
      {contentList[activeTabKey]}
    </Card>
  )
}


const Loader = () => (
  <div style={{ textAlign: "center", marginTop: "50px" }}>
    <Spin size="large" />
  </div>
)

const TabPane = Tabs.TabPane


const Example: React.FC = ({ query, codeExample, render, title }) => {
  const [showCode, toggleCode] = useState(false)

  return (
    <QueryRenderer
        query={query}
        cubejsApi={cubejs(HACKER_NEWS_DATASET_API_KEY)}
        loadSql
        render={({ resultSet, sqlQuery, error, loadingState }) => {
          if (error) {
            return (
              <Alert
                message="Error occured while loading your query"
                description={error.message}
                type="error"
              />
            )
          }

          if (resultSet && !loadingState.isLoading) {
            return (
              <Card
                title={title || "Example"}
                extra={
                  <Button
                    onClick={() =>
                      toggleCode(!this.state.showCode)
                    }
                    icon="code"
                    size="small"
                    type={showCode ? "primary" : "default"}
                  >
                    {showCode ? "Hide Code" : "Show Code"}
                  </Button>
                }
              >
                {render({ resultSet, error })}
                {showCode && (
                  <CodeExample
                    resultSet={resultSet}
                    codeExample={codeExample}
                    sqlQuery={sqlQuery}
                  />
                )}
              </Card>
            )
          }

          return <Loader />
        }}
      />    
  )
}

export default Example

推荐阅读