javascript - 我需要下面的代码写成 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;
解决方案
将类转换为功能组件非常容易。
记住这些步骤:
- 类=>常量
// Class
export class Example
// FC
export const Example
- 组件生命周期=>使用效果
// Class lifecycle
componentDidMount() {
// logic here
}
// FC
useEffect(() => {
// logic here
})
- 渲染=>返回
// Class
render () {
return (<Component/>)
}
// FC
return (<Component />)`
- 构造函数=> useState
// Class
constructor(props) {
this.state.val = props.val
}
// FC
const [val, setVal] = useState(props.val)
- 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
推荐阅读
- docker - 尝试使用 Let's Encrypt 保护 Nginx,但无法使用非 root 用户访问 /etc/letsencrypt/live 中的 .pem 文件
- scala - Spark build.sbt 文件版本控制
- javascript - 如何使用玩笑测试带有链承诺的类?
- python - Python问题:从一个文件夹中读取多个json文件只加载一个json
- python - 同时在点几何和其他列上合并 GeoDataFrames
- javascript - 改变 MediaRecorder 和 canvas.captureStream 的质量?
- python-3.x - Python最小化目标函数来估计模型参数
- vuejs2 - Vue.js - v-model 不跟踪动态数据的变化?
- azure - 查询 Azure APIM 诊断日志
- google-app-engine - 如何清除 Google Cloud Platform 中的 Stackdriver 日志?