<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>eth.mirror.xyz</title>
        <link>https://paragraph.com/@eth-mirror-xyz</link>
        <description>undefined</description>
        <lastBuildDate>Thu, 04 Jun 2026 06:58:31 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[WalletConnect解析]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/walletconnect</link>
            <guid>FyKRUvd0eofOEpdewxda</guid>
            <pubDate>Mon, 15 Nov 2021 05:21:13 GMT</pubDate>
            <description><![CDATA[01 WalletConnect 能干什么 它是⼀个基于⼆维码建立连接的基础通讯设施。你可以在它的基础上去建⽴各种交互，它默认的交互协议都是与以太坊的交互。当然你也可以做能够想象到的各种事，可以不只局限于 Dapp 通讯交互，如果你把默认的以太坊协议改掉，也意味着你将与其他⽀持 WalletConnect 钱包、Dapp 脱离关系，互不兼容。 现在出现了很多针对电脑这种大屏幕的 Dapp 应用，在 WalletConnect 没有出现之前，必须使用Chrome 插件或者桌面端钱包来授权操作，这让原本使用移动端钱包的用户操作和使用习惯出现了割裂感，还需另外操作下载插件或钱包，再将私钥导⼊进去。 02 WalletConnect 消息通讯工作原理 WalletConnect 建立连接原理 Topic 名词解释：文本意思为“主题”，在 WalletConnect 中钱包端与 Dapp 端各有⼀个 Topic 主题，让对方订阅，这样就形成了⼀个可以相互通信的通道。Dapp 端与中继服务器建立 Socket 连接；Dapp 端⽣成 Dapp ClientID（监听该 Topic 会得到发送...]]></description>
            <content:encoded><![CDATA[<p><strong>01 WalletConnect 能干什么</strong></p><p>它是⼀个基于⼆维码建立连接的基础通讯设施。你可以在它的基础上去建⽴各种交互，它默认的交互协议都是与以太坊的交互。当然你也可以做能够想象到的各种事，可以不只局限于 Dapp 通讯交互，如果你把默认的以太坊协议改掉，也意味着你将与其他⽀持 WalletConnect 钱包、Dapp 脱离关系，互不兼容。</p><p>现在出现了很多针对电脑这种大屏幕的 Dapp 应用，在 WalletConnect 没有出现之前，必须使用Chrome 插件或者桌面端钱包来授权操作，这让原本使用移动端钱包的用户操作和使用习惯出现了割裂感，还需另外操作下载插件或钱包，再将私钥导⼊进去。</p><p><strong>02 WalletConnect 消息通讯工作原理</strong></p><p>WalletConnect 建立连接原理</p><p>Topic 名词解释：文本意思为“主题”，在 WalletConnect 中钱包端与 Dapp 端各有⼀个 Topic 主题，让对方订阅，这样就形成了⼀个可以相互通信的通道。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/ed6e64a8f81496645ea58cc316523300a6e9a6af26590155b5a5a14f46866436.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/a7617810356883a96c301d1ac5e376749468fd6c020701954d71f3924f1cc964.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><ol><li><p>Dapp 端与中继服务器建立 Socket 连接；</p></li><li><p>Dapp 端⽣成 Dapp ClientID（监听该 Topic 会得到发送给 Dapp 的消息），Dapp Topic（监听该Topic 会得到 Dapp 发出的登陆请求），并订阅 Dapp ClientID；</p></li><li><p>Dapp 端向中继服务器发送 Topic 为 Dapp Topic 的信息，并携带 Dapp ClientID 信息；</p></li><li><p>Dapp 端展示⼆维码包含 Dapp Topic 信息，中继服务器的地址，密码；</p></li><li><p>钱包端扫描 Dapp 端的⼆维码，解析出⼆维码信息获得 Dapp Topic，中继服务器地址，密码；</p></li><li><p>钱包端与中继服务器建立socket 连接，然后产生 Wallet PeerID（监听该 Topic 可以获得发送给钱包端的消息），并订阅 Dapp Topic 和 Wallet PeerID ；</p></li><li><p>接下来钱包端将接收到中继服务器转发过来的 Dapp 的登陆请求；</p></li><li><p>钱包端处理是否同意 Dapp 的登陆，发送 Topic 为 Dapp ClientID 的消息，并把处理结果和Wallet PeerID 的信息传递回去；</p></li><li><p>此时连接建立成功，如果「Dapp」想给「钱包端」发送消息，则发送 Topic 为 Wallet PeerID 的信息即可；</p></li><li><p>如果「钱包端」想给「Dapp」发送消息，则发送 Topic 为 Dapp ClientID 的信息即可。</p></li></ol><p>钱包端 Topic 和 Dapp 端 Topic 两方共同组成了 Session。</p><p>WalletConnect 的 Session 生命周期才是 Dapp 与钱包双方建立的连接的生命周期，WebSocket 只是它的“通讯⼯具”，WebSocket 的断开不代表此次与钱包的连接断开。</p><p><strong>03 WalletConnect 通讯工作原理</strong></p><p>WalletConnect 只是⼀套通讯协议，双⽅通信什么信息都可以； WalletConnect 默认通过 WebHook 的⽅式来⽀持推送服务，你可以在⼿机 App 没有打开的情况下来通知⽤户处理信息； 如果有⼀方 A 断开 Socket 连接，另⼀⽅ B 发送消息会暂存在中继服务中，当下⼀次 A 与中继服务器建⽴ Socket 连接，并订阅相关的 Topic，才会将中继服务暂存的消息发送给 A。</p><p><strong>04 WalletConnect 消息安全如何保障</strong></p><p>使用 AES-256 对称加密来加密通讯的信息，HMAC-SHA256 做 Hash 签名； Dapp 端⽣成的⼆维码中包含对称加密的密码，⼿机端扫描该⼆维码获得密码，所以 Dapp ⼆维码不会过网传递。</p><p><strong>05 WalletConnect 如何快速接入推送</strong></p><p>底层做支持的技术 WebHook</p><p>WebHook 是⼀种 HTTP 回调：某些条件下触发的 HTTP POST 请求； WalletConnect 的中继服务中也有这个接受 WebHook URL 的 API 接⼝； WalletConnect 单独提供了 Firebase 推送服务。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/7b0024742d99cc17e35450b9d081a4d467fad3f3bdd4786a049fe491664e2473.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><ol><li><p>消息接收方将⼀个 URL 和想接收的消息发送给消息发送⽅；</p></li><li><p>消息发送方达成⼀定的条件，就会去调⽤ 消息接收⽅的 URL，来通知消息接收方接收消息。</p></li></ol><p>WalletConnect 推送使⽤流程</p><ol><li><p>⼿机端收到 Dapp 的登陆请求，⼿机端如果同意登陆请求，可以使⽤ Topic Dapp ClientID 和Firebase ID 向「推送服务」订阅消息；</p></li><li><p>「推送服务」收到 Topic 会继续向「中继服务」发送 WebHook 订阅 Topic；</p></li><li><p>如果「中继服务器」发现「推送服务」订阅的 Topic 有信息，它就会通知「推送服务」；</p></li><li><p>「推送服务」找到订阅相关 Topic 的 fitebase ID 发起推送。</p></li></ol><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/f4d39fac7760d222ec63d93a0dc063eeaf4374db0afd816cc827394a985e35f7.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p><strong>06 总结</strong></p><p>WalletConnect 是⼀种通过扫描 QR 码使⽤端到端加密技术将桌⾯ DApp 连接到移动设备的开放性协议。它开启了整个曾经只有Metamask 钱包可⽤的 DApps 世界。⽤户可以在不损害其私钥安全的情况下与任何 DApp 交互，并能在其移动设备上收到通知，签字同意任何交易请求。</p><p>本文链接：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.8btc.com/media/642335">https://www.8btc.com/media/642335</a> 转载请注明文章出处</p>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[在Mac中展示目录文件数]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/mac</link>
            <guid>q4Y0nr6i9gxAMk48oh0a</guid>
            <pubDate>Thu, 04 Nov 2021 04:05:18 GMT</pubDate>
            <description><![CDATA[brew install tree（当然，你得先安装homebrew) 等待安装完成，我们就可以使用tree命令了。 首先使用tree --help查看帮助，所有的用法都在里面。 下面介绍两个常用的用法。 在目录遍历时使用 -L 参数指定遍历层级% tree -L 1 . ├── dist ├── node_modules ├── package.json ├── src ├── webpack.config.js └── yarn.lock 把一个目录的结构树导出到文件 Readme.md ,可以使用tree -L 2 >README.md，打开README.md 可以在markdown中编辑。]]></description>
            <content:encoded><![CDATA[<p><code>brew install tree</code>（当然，你得先安装homebrew)</p><p>等待安装完成，我们就可以使用tree命令了。 首先使用<code>tree --help</code>查看帮助，所有的用法都在里面。</p><p>下面介绍两个常用的用法。</p><p>在目录遍历时使用 -L 参数指定遍历层级</p><pre data-type="codeBlock" text="% tree -L 1
.
├── dist
├── node_modules
├── package.json
├── src
├── webpack.config.js
└── yarn.lock
"><code><span class="hljs-operator">%</span> tree <span class="hljs-operator">-</span>L <span class="hljs-number">1</span>
.
├── dist
├── node_modules
├── package.json
├── src
├── webpack.config.js
└── yarn.lock
</code></pre><p>把一个目录的结构树导出到文件 Readme.md ,可以使用<code>tree -L 2 &gt;README.md</code>，打开README.md 可以在markdown中编辑。</p>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[Go语言实现查询以太坊代币余额]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/go-2</link>
            <guid>k8CpvX7gj6Gh1RAC6Eq5</guid>
            <pubDate>Thu, 28 Oct 2021 10:46:17 GMT</pubDate>
            <description><![CDATA[import ( "fmt" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" "github.com/honorjoey/ethtest/contracts" ) func BalanceToken(Net, tokenAddress, address string) (string, error) { client, err := ethclient.Dial(Net) if err != nil { return "", err } // Golem (GNT) Address tokenAddr := common.HexToAddress(tokenAddress) instance, err := contracts.NewTobaToken(tokenAddr, client) if err != nil { return "", err } a...]]></description>
            <content:encoded><![CDATA[<pre data-type="codeBlock" text="import (
    &quot;fmt&quot;
    &quot;github.com/ethereum/go-ethereum/accounts/abi/bind&quot;
    &quot;github.com/ethereum/go-ethereum/common&quot;
    &quot;github.com/ethereum/go-ethereum/ethclient&quot;
    &quot;github.com/honorjoey/ethtest/contracts&quot;
)

func BalanceToken(Net, tokenAddress, address string) (string, error) {
    client, err := ethclient.Dial(Net)
    if err != nil {
        return &quot;&quot;, err
    }

    // Golem (GNT) Address
    tokenAddr := common.HexToAddress(tokenAddress)
    instance, err := contracts.NewTobaToken(tokenAddr, client)
    if err != nil {
        return &quot;&quot;, err
    }

    addr := common.HexToAddress(address)
    bal, err := instance.BalanceOf(&amp;bind.CallOpts{}, addr)
    if err != nil {
        return &quot;&quot;, err
    }
    //bal.Div(bal, big.NewInt(1000000000000000000))
    return bal.String(), nil
}

func main() {
    bal, _ := BalanceToken(&quot;ETHNetAddress&quot;, &quot;contractAddress&quot;, &quot;ethAddress&quot;)
    fmt.Println(bal)
}
"><code><span class="hljs-keyword">import</span> (
    <span class="hljs-string">"fmt"</span>
    <span class="hljs-string">"github.com/ethereum/go-ethereum/accounts/abi/bind"</span>
    <span class="hljs-string">"github.com/ethereum/go-ethereum/common"</span>
    <span class="hljs-string">"github.com/ethereum/go-ethereum/ethclient"</span>
    <span class="hljs-string">"github.com/honorjoey/ethtest/contracts"</span>
)

<span class="hljs-title">func</span> <span class="hljs-title">BalanceToken</span>(<span class="hljs-title">Net</span>, <span class="hljs-title">tokenAddress</span>, <span class="hljs-title"><span class="hljs-keyword">address</span></span> <span class="hljs-title"><span class="hljs-keyword">string</span></span>) (<span class="hljs-title"><span class="hljs-keyword">string</span></span>, <span class="hljs-title"><span class="hljs-keyword">error</span></span>) {
    <span class="hljs-title">client</span>, <span class="hljs-title">err</span> :<span class="hljs-operator">=</span> <span class="hljs-title">ethclient</span>.<span class="hljs-title">Dial</span>(<span class="hljs-title">Net</span>)
    <span class="hljs-title"><span class="hljs-keyword">if</span></span> <span class="hljs-title">err</span> <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-title">nil</span> {
        <span class="hljs-title"><span class="hljs-keyword">return</span></span> <span class="hljs-string">""</span>, <span class="hljs-title">err</span>
    }

    <span class="hljs-comment">// Golem (GNT) Address</span>
    <span class="hljs-title">tokenAddr</span> :<span class="hljs-operator">=</span> <span class="hljs-title">common</span>.<span class="hljs-title">HexToAddress</span>(<span class="hljs-title">tokenAddress</span>)
    <span class="hljs-title">instance</span>, <span class="hljs-title">err</span> :<span class="hljs-operator">=</span> <span class="hljs-title">contracts</span>.<span class="hljs-title">NewTobaToken</span>(<span class="hljs-title">tokenAddr</span>, <span class="hljs-title">client</span>)
    <span class="hljs-title"><span class="hljs-keyword">if</span></span> <span class="hljs-title">err</span> <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-title">nil</span> {
        <span class="hljs-title"><span class="hljs-keyword">return</span></span> <span class="hljs-string">""</span>, <span class="hljs-title">err</span>
    }

    <span class="hljs-title">addr</span> :<span class="hljs-operator">=</span> <span class="hljs-title">common</span>.<span class="hljs-title">HexToAddress</span>(<span class="hljs-title"><span class="hljs-keyword">address</span></span>)
    <span class="hljs-title">bal</span>, <span class="hljs-title">err</span> :<span class="hljs-operator">=</span> <span class="hljs-title">instance</span>.<span class="hljs-title">BalanceOf</span>(<span class="hljs-operator">&#x26;</span><span class="hljs-title">bind</span>.<span class="hljs-title">CallOpts</span>{}, <span class="hljs-title">addr</span>)
    <span class="hljs-title"><span class="hljs-keyword">if</span></span> <span class="hljs-title">err</span> <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-title">nil</span> {
        <span class="hljs-title"><span class="hljs-keyword">return</span></span> <span class="hljs-string">""</span>, <span class="hljs-title">err</span>
    }
    <span class="hljs-comment">//bal.Div(bal, big.NewInt(1000000000000000000))</span>
    <span class="hljs-title"><span class="hljs-keyword">return</span></span> <span class="hljs-title">bal</span>.<span class="hljs-title">String</span>(), <span class="hljs-title">nil</span>
}

<span class="hljs-title">func</span> <span class="hljs-title">main</span>() {
    <span class="hljs-title">bal</span>, <span class="hljs-title"><span class="hljs-keyword">_</span></span> :<span class="hljs-operator">=</span> <span class="hljs-title">BalanceToken</span>(<span class="hljs-string">"ETHNetAddress"</span>, <span class="hljs-string">"contractAddress"</span>, <span class="hljs-string">"ethAddress"</span>)
    <span class="hljs-title">fmt</span>.<span class="hljs-title">Println</span>(<span class="hljs-title">bal</span>)
}
</code></pre>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[linux 查看自己所在的公网ip]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/linux-ip</link>
            <guid>DR455ejkWabOn7Bzk64X</guid>
            <pubDate>Wed, 27 Oct 2021 03:39:23 GMT</pubDate>
            <description><![CDATA[curl members.3322.org/dyndns/getip 其他的方法还有:curl icanhazip.com curl ifconfig.me curl curlmyip.com curl ip.appspot.com curl ipinfo.io/ip curl ipecho.net/plain curl www.trackip.net/i]]></description>
            <content:encoded><![CDATA[<p>curl members.3322.org/dyndns/getip</p><p>其他的方法还有:</p><pre data-type="codeBlock" text="curl icanhazip.com  
curl ifconfig.me  
curl curlmyip.com  
curl ip.appspot.com  
curl ipinfo.io/ip  
curl ipecho.net/plain  
curl www.trackip.net/i  
"><code>curl icanhazip.com  
curl ifconfig.me  
curl curlmyip.com  
curl ip.appspot.com  
curl ipinfo.io/ip  
curl ipecho.net/plain  
curl www.trackip.net/i  
</code></pre>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[【Go第三方包代理】Go第三方包代理设置 — GOPROXY]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/go-go-goproxy</link>
            <guid>vE84zZMUoud1aPvlbUP6</guid>
            <pubDate>Thu, 21 Oct 2021 04:00:29 GMT</pubDate>
            <description><![CDATA[Go第三方包代理设置 — GOPROXY 由于国内 墙 的特殊存在，加上现在对翻墙软件的打压，想看看外面的世界越来越难了。 使用 Go 语言的小伙伴们应该也对 Go语言官网 被墙感到苦恼，很多文档和第三方包还得通过一些第三方渠道获得；尤其是 golang.org/x 使用广泛，但是被墙了。。。 Go 在 1.11 版本中放出了 mod 管理机制，在涉及到 第三方库 和 第三方库里用 golang.org/x 的时候，真是让人不爽。。。 下面来介绍一下 GOPROXY 方式去正常使用这些工具。 PS：可以翻墙的小伙伴可以略过所有内容。 一、传统非代理方式解决第三方包问题 go mod 提供了 replace 方式来指定替换包的地址；当然，如果第三方包中引用墙外的包，就需要手动修改他们了，不如代理方式方便； 使用方式如下：module github.com/exercise require ( golang.org/x/text v0.3.0 gopkg.in/yaml.v2 v2.1.0 ) replace ( golang.org/x/text => github.com/gol...]]></description>
            <content:encoded><![CDATA[<p>Go第三方包代理设置 — GOPROXY 由于国内 墙 的特殊存在，加上现在对翻墙软件的打压，想看看外面的世界越来越难了。</p><p>使用 Go 语言的小伙伴们应该也对 Go语言官网 被墙感到苦恼，很多文档和第三方包还得通过一些第三方渠道获得；尤其是 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://golang.org/x">golang.org/x</a> 使用广泛，但是被墙了。。。</p><p>Go 在 1.11 版本中放出了 mod 管理机制，在涉及到 第三方库 和 第三方库里用 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://golang.org/x">golang.org/x</a> 的时候，真是让人不爽。。。</p><p>下面来介绍一下 GOPROXY 方式去正常使用这些工具。</p><p>PS：可以翻墙的小伙伴可以略过所有内容。</p><p>一、传统非代理方式解决第三方包问题 go mod 提供了 replace 方式来指定替换包的地址；当然，如果第三方包中引用墙外的包，就需要手动修改他们了，不如代理方式方便；</p><p>使用方式如下：</p><pre data-type="codeBlock" text="module github.com/exercise

require (
    golang.org/x/text v0.3.0
    gopkg.in/yaml.v2 v2.1.0 
)

replace (
    golang.org/x/text =&gt; github.com/golang/text v0.3.0
)
"><code>module github.com/exercise

<span class="hljs-built_in">require</span> (
    golang.org/x<span class="hljs-operator">/</span>text v0<span class="hljs-number">.3</span><span class="hljs-number">.0</span>
    gopkg.in/yaml.v2 v2<span class="hljs-number">.1</span><span class="hljs-number">.0</span> 
)

replace (
    golang.org/x<span class="hljs-operator">/</span>text <span class="hljs-operator">=</span><span class="hljs-operator">></span> github.com/golang<span class="hljs-operator">/</span>text v0<span class="hljs-number">.3</span><span class="hljs-number">.0</span>
)
</code></pre><h2 id="h-goproxy" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">二、GOPROXY的两个地址</h2><blockquote><p>主要有两个地址：</p><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://goproxy.io/">https://goproxy.io</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://athens.azurefd.net/">https://athens.azurefd.net</a></p></li></ul><p>根据个人喜好随意选择吧。</p></blockquote><h3 id="h-1goproxyio" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">1、goproxy.io</h3><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://goproxy.io/">官网</a></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/befade4828e1628512807342a8b56334683fd77e9b283bd1b06ed01f00fff98e.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>原理图</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/b4d706eeb1003525c55cb573f416e7aa1ef025930a54b5506febf848aa652bd0.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h3 id="h-2athens" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">2、Athens</h3><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.gomods.io/">官网</a></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/1d036f2192e3f86f467eb93243b69d615d9dc39341c85ccdffdb2a3b31990369.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-goland" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">三、GoLand设置</h2><blockquote><ol><li><p>路径：GoLand —&gt; Perferences —&gt; Go —&gt; Go Modules（vgo）—&gt; Proxy；</p></li><li><p>设置上面给出的地址；</p></li><li><p>重启即可使用；</p></li></ol></blockquote><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">四、命令行设置环境变量</h2><blockquote><p>此处以 Mac为例，给出示例图片；</p><p>只要 export 加入到 环境变量里，一些墙外的第三方包就可以正常获取到了；</p><p>windows系统的设置方法可以看 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://goproxy.io/">goproxy.io</a> 的设置文档；</p></blockquote><pre data-type="codeBlock" text="~ $ export GOPROXY=https://goproxy.io
~ $ echo $GOPROXY
https://goproxy.io
"><code>~ $ <span class="hljs-built_in">export</span> GOPROXY=https://goproxy.io
~ $ <span class="hljs-built_in">echo</span> <span class="hljs-variable">$GOPROXY</span>
https://goproxy.io
</code></pre><p>原文链接：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blog.csdn.net/tmt123421/article/details/88665248">https://blog.csdn.net/tmt123421/article/details/88665248</a></p>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[react native android 应用状态（前端或后台）的判断]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/react-native-android</link>
            <guid>MfN3uovMcDsCMr2FyehU</guid>
            <pubDate>Thu, 21 Oct 2021 03:48:29 GMT</pubDate>
            <description><![CDATA[当Android应用程序被暂时放到了后台，或者又重新回到前台，是否有相应的事件可以处理到？ 例如，当你的应用暂时放到了后台，是否应该做出一些操作，暂时保存界面上的数据？ 可以参考：https://github.com/wix/react-native-navigation/issues/839 官方文档：https://facebook.github.io/react-native/docs/appstate.html 官方示例代码：import React, {Component} from 'react' import {AppState, Text} from 'react-native' class AppStateExample extends Component { state = { appState: AppState.currentState } componentDidMount() { AppState.addEventListener('change', this._handleAppStateChange); } componentWillUnmount...]]></description>
            <content:encoded><![CDATA[<p>当Android应用程序被暂时放到了后台，或者又重新回到前台，是否有相应的事件可以处理到？</p><p>例如，当你的应用暂时放到了后台，是否应该做出一些操作，暂时保存界面上的数据？</p><p>可以参考：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/wix/react-native-navigation/issues/839">https://github.com/wix/react-native-navigation/issues/839</a></p><p>官方文档：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://facebook.github.io/react-native/docs/appstate.html">https://facebook.github.io/react-native/docs/appstate.html</a></p><p>官方示例代码：</p><pre data-type="codeBlock" text="import React, {Component} from &apos;react&apos;
import {AppState, Text} from &apos;react-native&apos;

class AppStateExample extends Component {

  state = {
    appState: AppState.currentState
  }

  componentDidMount() {
    AppState.addEventListener(&apos;change&apos;, this._handleAppStateChange);
  }

  componentWillUnmount() {
    AppState.removeEventListener(&apos;change&apos;, this._handleAppStateChange);
  }

  _handleAppStateChange = (nextAppState) =&gt; {
    if (this.state.appState.match(/inactive|background/) &amp;&amp; nextAppState === &apos;active&apos;) {
      console.log(&apos;App has come to the foreground!&apos;)
    }
    this.setState({appState: nextAppState});
  }

  render() {
    return (
      &lt;Text&gt;Current state is: {this.state.appState}&lt;/Text&gt;
    );
  }
}
"><code><span class="hljs-keyword">import</span> <span class="hljs-title">React</span>, {<span class="hljs-title">Component</span>} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'react'</span>
<span class="hljs-title"><span class="hljs-keyword">import</span></span> {<span class="hljs-title">AppState</span>, <span class="hljs-title">Text</span>} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'react-native'</span>

<span class="hljs-title">class</span> <span class="hljs-title">AppStateExample</span> <span class="hljs-title">extends</span> <span class="hljs-title">Component</span> {

  <span class="hljs-title">state</span> <span class="hljs-operator">=</span> {
    <span class="hljs-title">appState</span>: <span class="hljs-title">AppState</span>.<span class="hljs-title">currentState</span>
  }

  <span class="hljs-title">componentDidMount</span>() {
    <span class="hljs-title">AppState</span>.<span class="hljs-title">addEventListener</span>(<span class="hljs-string">'change'</span>, <span class="hljs-title"><span class="hljs-built_in">this</span></span>.<span class="hljs-title">_handleAppStateChange</span>);
  }

  componentWillUnmount() {
    AppState.removeEventListener(<span class="hljs-string">'change'</span>, <span class="hljs-built_in">this</span>._handleAppStateChange);
  }

  _handleAppStateChange <span class="hljs-operator">=</span> (nextAppState) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.state.appState.match(<span class="hljs-operator">/</span>inactive<span class="hljs-operator">|</span>background<span class="hljs-operator">/</span>) <span class="hljs-operator">&#x26;</span><span class="hljs-operator">&#x26;</span> nextAppState <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'active'</span>) {
      console.log(<span class="hljs-string">'App has come to the foreground!'</span>)
    }
    <span class="hljs-built_in">this</span>.setState({appState: nextAppState});
  }

  render() {
    <span class="hljs-keyword">return</span> (
      <span class="hljs-operator">&#x3C;</span>Text<span class="hljs-operator">></span>Current state <span class="hljs-keyword">is</span>: {<span class="hljs-built_in">this</span>.state.appState}<span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>Text<span class="hljs-operator">></span>
    );
  }
}
</code></pre><p>做法是：引用AppState</p><pre data-type="codeBlock" text="import { AppState } from &apos;react-native&apos;;
"><code><span class="hljs-keyword">import</span> { <span class="hljs-title class_">AppState</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
</code></pre><p>在组件的componentDidMount事件中，增加以下代码</p><pre data-type="codeBlock" text="componentDidMount() {
        console.log(&apos;componentDidMount================&apos;);
        AppState.addEventListener(&apos;change&apos;, (state) =&gt; {
            if (state === &apos;active&apos;) {
                console.log(&apos;state active&apos;);
            } else if (state === &apos;background&apos;) {
                console.log(&apos;background&apos;);
            } else if (state === &apos;inactive&apos;) {
                console.log(&apos;inactive&apos;);
            }
        });
    }
"><code>componentDidMount() {
        console.log(<span class="hljs-string">'componentDidMount================'</span>);
        AppState.addEventListener(<span class="hljs-string">'change'</span>, (state) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
            <span class="hljs-keyword">if</span> (state <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'active'</span>) {
                console.log(<span class="hljs-string">'state active'</span>);
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (state <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'background'</span>) {
                console.log(<span class="hljs-string">'background'</span>);
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (state <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'inactive'</span>) {
                console.log(<span class="hljs-string">'inactive'</span>);
            }
        });
    }
</code></pre><p>App States <strong>active</strong> - 该应用程序在前台运行 <strong>background</strong> - 该应用程序正在后台运行。用户是： 在另一个应用中 在主屏幕上 [Android]在另一个Activity（即使它是由您的应用程序启动） <strong>inactive</strong> - 这是在前景和背景之间转换时以及在处于非活动状态期间发生的状态，例如进入多任务处理视图或来电时</p>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[React Native 监听Back双击退出实现+APP前后台状态监听]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/react-native-back-app</link>
            <guid>xOHuizZ79ujfjs60CFly</guid>
            <pubDate>Thu, 21 Oct 2021 03:46:14 GMT</pubDate>
            <description><![CDATA[关于前后台监听，HOME直接进入后台不执行component相关周期函数，back后台是执行的，back后返回应该是重新render了，所以监听HOME或者BACK可以一同使用APPState的状态码来操作，APPState是有三个状态码的，有一个不常用就没写import React, { Component } from 'react'; import { ToastAndroid, AppState, BackHandler, TouchableHighlight, Platform, StyleSheet, Text, View, Alert } from 'react-native'; const instructions = Platform.select({ ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu', android: 'Double tap R on your keyboard to reload,\n' + 'Shake or press menu button for dev ...]]></description>
            <content:encoded><![CDATA[<p>关于前后台监听，HOME直接进入后台不执行component相关周期函数，back后台是执行的，back后返回应该是重新render了，所以监听HOME或者BACK可以一同使用APPState的状态码来操作，APPState是有三个状态码的，有一个不常用就没写</p><pre data-type="codeBlock" text="import React, { Component } from &apos;react&apos;;
import {
  ToastAndroid,
  AppState,
  BackHandler,
  TouchableHighlight,
  Platform,
  StyleSheet,
  Text,
  View,
  Alert
} from &apos;react-native&apos;;

const instructions = Platform.select({
  ios: &apos;Press Cmd+R to reload,\n&apos; +
    &apos;Cmd+D or shake for dev menu&apos;,
  android: &apos;Double tap R on your keyboard to reload,\n&apos; +
    &apos;Shake or press menu button for dev menu&apos;,
});


const lastBackPressed = Date.now();

type State = {
  test: string,
};

export default class App extends Component&lt;Props,State&gt;{

constructor(props: Props){
  super(props);
  this.state = {
    test: &quot;hello&quot;,
  };
}

  //组件加载之后添加监听
  componentDidMount() {
    if(Platform.OS === &apos;android&apos;) BackHandler.addEventListener(&apos;hardwareBackPress&apos;, this._onBackPressed);
    AppState.addEventListener(&apos;change&apos;, this._onAppStateChanged);
  }

  //组件卸载之前移除监听
  componentWillUnmount() {
    if(Platform.OS === &apos;android&apos;) BackHandler.removeEventListener(&apos;hardwareBackPress&apos;, this._onBackPressed);
    AppState.removeEventListener(&apos;change&apos;, this._onAppStateChanged);
  }

  _onBackPressed() {
    if (lastBackPressed &amp;&amp; lastBackPressed + 2000 &gt;= Date.now()) {
        BackHandler.exitApp();
      }
      lastBackPressed = Date.now();
      ToastAndroid.show(&apos;再按一次退出应用&apos;, ToastAndroid.SHORT);
      return true;
  }

  _onAppStateChanged() {
    switch (AppState.currentState) {
      case &quot;active&quot;:
        console.log(&quot;active&quot;);
        break;
      case &quot;background&quot;:
        console.log(&quot;background&quot;);
        break;
      default:

    }
  }
  render() {
    return (
      &lt;View style={styles.container}&gt;
        &lt;Text style={styles.welcome}&gt;
          Welcome to React Native!
        &lt;/Text&gt;
        &lt;Text style={styles.instructions}&gt;
          To get started, edit App.js
        &lt;/Text&gt;
        &lt;TouchableHighlight onPress={
                ()=&gt; {
                    this.setState({test: &quot;aaaa&quot;});
                }
            }&gt;
                &lt;Text&gt;{this.state.test}&lt;/Text&gt;
            &lt;/TouchableHighlight&gt;
        &lt;Text style={styles.instructions}&gt;
          {instructions}
        &lt;/Text&gt;
      &lt;/View&gt;
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: &apos;center&apos;,
    alignItems: &apos;center&apos;,
    backgroundColor: &apos;#F5FCFF&apos;,
  },
  welcome: {
    fontSize: 20,
    textAlign: &apos;center&apos;,
    margin: 10,
  },
  instructions: {
    textAlign: &apos;center&apos;,
    color: &apos;#333333&apos;,
    marginBottom: 5,
  },
});
"><code><span class="hljs-keyword">import</span> <span class="hljs-title">React</span>, { <span class="hljs-title">Component</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> {
  <span class="hljs-title">ToastAndroid</span>,
  <span class="hljs-title">AppState</span>,
  <span class="hljs-title">BackHandler</span>,
  <span class="hljs-title">TouchableHighlight</span>,
  <span class="hljs-title">Platform</span>,
  <span class="hljs-title">StyleSheet</span>,
  <span class="hljs-title">Text</span>,
  <span class="hljs-title">View</span>,
  <span class="hljs-title">Alert</span>
} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'react-native'</span>;

const instructions <span class="hljs-operator">=</span> Platform.select({
  ios: <span class="hljs-string">'Press Cmd+R to reload,\n'</span> <span class="hljs-operator">+</span>
    <span class="hljs-string">'Cmd+D or shake for dev menu'</span>,
  android: <span class="hljs-string">'Double tap R on your keyboard to reload,\n'</span> <span class="hljs-operator">+</span>
    <span class="hljs-string">'Shake or press menu button for dev menu'</span>,
});


const lastBackPressed <span class="hljs-operator">=</span> Date.now();

<span class="hljs-keyword">type</span> State <span class="hljs-operator">=</span> {
  test: <span class="hljs-keyword">string</span>,
};

export default class App extends Component<span class="hljs-operator">&#x3C;</span>Props,State<span class="hljs-operator">></span>{

<span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params">props: Props</span>)</span>{
  <span class="hljs-built_in">super</span>(props);
  <span class="hljs-built_in">this</span>.state <span class="hljs-operator">=</span> {
    test: <span class="hljs-string">"hello"</span>,
  };
}

  <span class="hljs-comment">//组件加载之后添加监听</span>
  componentDidMount() {
    <span class="hljs-keyword">if</span>(Platform.OS <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'android'</span>) BackHandler.addEventListener(<span class="hljs-string">'hardwareBackPress'</span>, <span class="hljs-built_in">this</span>._onBackPressed);
    AppState.addEventListener(<span class="hljs-string">'change'</span>, <span class="hljs-built_in">this</span>._onAppStateChanged);
  }

  <span class="hljs-comment">//组件卸载之前移除监听</span>
  componentWillUnmount() {
    <span class="hljs-keyword">if</span>(Platform.OS <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-string">'android'</span>) BackHandler.removeEventListener(<span class="hljs-string">'hardwareBackPress'</span>, <span class="hljs-built_in">this</span>._onBackPressed);
    AppState.removeEventListener(<span class="hljs-string">'change'</span>, <span class="hljs-built_in">this</span>._onAppStateChanged);
  }

  _onBackPressed() {
    <span class="hljs-keyword">if</span> (lastBackPressed <span class="hljs-operator">&#x26;</span><span class="hljs-operator">&#x26;</span> lastBackPressed <span class="hljs-operator">+</span> <span class="hljs-number">2000</span> <span class="hljs-operator">></span><span class="hljs-operator">=</span> Date.now()) {
        BackHandler.exitApp();
      }
      lastBackPressed <span class="hljs-operator">=</span> Date.now();
      ToastAndroid.show(<span class="hljs-string">'再按一次退出应用'</span>, ToastAndroid.SHORT);
      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  }

  _onAppStateChanged() {
    switch (AppState.currentState) {
      case <span class="hljs-string">"active"</span>:
        console.log(<span class="hljs-string">"active"</span>);
        <span class="hljs-keyword">break</span>;
      case <span class="hljs-string">"background"</span>:
        console.log(<span class="hljs-string">"background"</span>);
        <span class="hljs-keyword">break</span>;
      default:

    }
  }
  render() {
    <span class="hljs-keyword">return</span> (
      <span class="hljs-operator">&#x3C;</span>View style<span class="hljs-operator">=</span>{styles.container}<span class="hljs-operator">></span>
        <span class="hljs-operator">&#x3C;</span>Text style<span class="hljs-operator">=</span>{styles.welcome}<span class="hljs-operator">></span>
          Welcome to React Native<span class="hljs-operator">!</span>
        <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>Text<span class="hljs-operator">></span>
        <span class="hljs-operator">&#x3C;</span>Text style<span class="hljs-operator">=</span>{styles.instructions}<span class="hljs-operator">></span>
          To get started, edit App.js
        <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>Text<span class="hljs-operator">></span>
        <span class="hljs-operator">&#x3C;</span>TouchableHighlight onPress<span class="hljs-operator">=</span>{
                ()<span class="hljs-operator">=</span><span class="hljs-operator">></span> {
                    <span class="hljs-built_in">this</span>.setState({test: <span class="hljs-string">"aaaa"</span>});
                }
            }<span class="hljs-operator">></span>
                <span class="hljs-operator">&#x3C;</span>Text<span class="hljs-operator">></span>{<span class="hljs-built_in">this</span>.state.test}<span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>Text<span class="hljs-operator">></span>
            <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>TouchableHighlight<span class="hljs-operator">></span>
        <span class="hljs-operator">&#x3C;</span>Text style<span class="hljs-operator">=</span>{styles.instructions}<span class="hljs-operator">></span>
          {instructions}
        <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>Text<span class="hljs-operator">></span>
      <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>View<span class="hljs-operator">></span>
    );
  }
}

const styles <span class="hljs-operator">=</span> StyleSheet.create({
  container: {
    flex: <span class="hljs-number">1</span>,
    justifyContent: <span class="hljs-string">'center'</span>,
    alignItems: <span class="hljs-string">'center'</span>,
    backgroundColor: <span class="hljs-string">'#F5FCFF'</span>,
  },
  welcome: {
    fontSize: <span class="hljs-number">20</span>,
    textAlign: <span class="hljs-string">'center'</span>,
    margin: <span class="hljs-number">10</span>,
  },
  instructions: {
    textAlign: <span class="hljs-string">'center'</span>,
    color: <span class="hljs-string">'#333333'</span>,
    marginBottom: <span class="hljs-number">5</span>,
  },
});
</code></pre>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[React-Native如何复制文本到剪贴板]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/react-native</link>
            <guid>fBLNe4sNQYhZZpSJrp0k</guid>
            <pubDate>Thu, 21 Oct 2021 03:37:43 GMT</pubDate>
            <description><![CDATA[React-Native自带Clipboard API，使用Clipboard可以在iOS和Android的剪贴板中读写内容。 官方API里面只有复制到剪贴板和从剪贴板读取内容的两个方法：static getString()获取剪贴板的文本内容，返回一个Promise语句。static setString(content: string)设置剪贴板的文本内容。你可以用下面的方式来调用。import React from 'react' import PropTypes from 'prop-types' import { View, Text, TouchableWithoutFeedback, Clipboard, } from 'react-native' export default class Example extends React.Component { constructor(props) { super(props); this.state = { text:'我是文本' } } async copy(){ Clipboard.setString(this.st...]]></description>
            <content:encoded><![CDATA[<p>React-Native自带<strong>Clipboard</strong> API，使用<strong>Clipboard</strong>可以在iOS和Android的剪贴板中读写内容。</p><p>官方API里面只有复制到剪贴板和从剪贴板读取内容的两个方法：</p><blockquote><h4 id="h-static-getstring" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">static getString()</h4><p>获取剪贴板的文本内容，返回一个Promise语句。</p><h4 id="h-static-setstringcontent-string" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">static setString(content: string)</h4><p>设置剪贴板的文本内容。你可以用下面的方式来调用。</p></blockquote><pre data-type="codeBlock" text="import React from &apos;react&apos;
import PropTypes from &apos;prop-types&apos;
import {
    View,
    Text,
    TouchableWithoutFeedback,
    Clipboard,
} from &apos;react-native&apos;

export default class Example extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            text:&apos;我是文本&apos;
        }
    }
    async copy(){
        Clipboard.setString(this.state.text);
        let  str = await Clipboard.getString()；
        console.log(str)//我是文本
    }
    render() {
        const { text } = this.state;
        return(
              &lt;View&gt;
                  &lt;Text&gt;{text}&lt;/Text&gt;
                  &lt;TouchableWithoutFeedback onPress={this.copy.bind(this)}&gt;
                      &lt;View&gt;
                          &lt;Text&gt;点击复制到剪贴板&lt;/Text&gt;
                      &lt;/View&gt;
                  &lt;/TouchableWithoutFeedback&gt;
              &lt;/View&gt;
        )
    }
}
"><code><span class="hljs-keyword">import</span> <span class="hljs-title">React</span> <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'react'</span>
<span class="hljs-title"><span class="hljs-keyword">import</span></span> <span class="hljs-title">PropTypes</span> <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'prop-types'</span>
<span class="hljs-title"><span class="hljs-keyword">import</span></span> {
    <span class="hljs-title">View</span>,
    <span class="hljs-title">Text</span>,
    <span class="hljs-title">TouchableWithoutFeedback</span>,
    <span class="hljs-title">Clipboard</span>,
} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'react-native'</span>

<span class="hljs-title">export</span> <span class="hljs-title">default</span> <span class="hljs-title">class</span> <span class="hljs-title">Example</span> <span class="hljs-title">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> {
    <span class="hljs-title"><span class="hljs-keyword">constructor</span></span>(<span class="hljs-title">props</span>) {
        <span class="hljs-title"><span class="hljs-built_in">super</span></span>(<span class="hljs-title">props</span>);
        <span class="hljs-built_in">this</span>.state <span class="hljs-operator">=</span> {
            text:<span class="hljs-string">'我是文本'</span>
        }
    }
    async copy(){
        Clipboard.setString(<span class="hljs-built_in">this</span>.state.text);
        let  str <span class="hljs-operator">=</span> await Clipboard.getString()；
        console.log(str)<span class="hljs-comment">//我是文本</span>
    }
    render() {
        const { text } <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.state;
        <span class="hljs-keyword">return</span>(
              <span class="hljs-operator">&#x3C;</span>View<span class="hljs-operator">></span>
                  <span class="hljs-operator">&#x3C;</span>Text<span class="hljs-operator">></span>{text}<span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>Text<span class="hljs-operator">></span>
                  <span class="hljs-operator">&#x3C;</span>TouchableWithoutFeedback onPress<span class="hljs-operator">=</span>{<span class="hljs-built_in">this</span>.copy.bind(<span class="hljs-built_in">this</span>)}<span class="hljs-operator">></span>
                      <span class="hljs-operator">&#x3C;</span>View<span class="hljs-operator">></span>
                          <span class="hljs-operator">&#x3C;</span>Text<span class="hljs-operator">></span>点击复制到剪贴板<span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>Text<span class="hljs-operator">></span>
                      <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>View<span class="hljs-operator">></span>
                  <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>TouchableWithoutFeedback<span class="hljs-operator">></span>
              <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span>View<span class="hljs-operator">></span>
        )
    }
}
</code></pre><p>目前暂时只支持复制文本和读取文本，实际应用中，我们可能希望能够部分复制，即类似复制从某个位置到某个位置的文本，这个操作如果后续看到的话，我会添加在这后面。</p>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[go中生成可执行文件]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/go</link>
            <guid>ZOa1mgJ1hA0oGwV9obFL</guid>
            <pubDate>Thu, 21 Oct 2021 03:24:25 GMT</pubDate>
            <description><![CDATA[一、简介这里介绍对go项目进行打包编译生成可执行文件，其实包含参数的传递、目标可执行文件类型、打包对象。二、使用go项目的编译命令为go build，编译包，生成可执行文件(包含main包),默认生成位置在当前目录下。 (注意不能生成包文件)。如下：go build 参数有： -ldflags：用于编译时设置变量值 -o：指定编译生成的目标文件名 -v:编译时显示包名 另外编译预设变量： GOOS:指定编译生成可执行文件的运行系统，常用的有：windows、linux、darwin GOARCH:指定编译生成可执行文件的运行系统架构，常用的有：amd64、arm 其中参数传递-ldflags的二级参数为：-X:设置包中的变量值 -s:去掉符号表，异常时没有文件名或行号信息 -w:去掉DWARF调试信息 三、示例3.1 带参数编译3.1.1 目标go文件 这里目标go文件param_main.go我放在with_param目录下。package main import "fmt" //参数定义，由外部传值 var ( Env string Version string ) func...]]></description>
            <content:encoded><![CDATA[<h3 id="h-" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">一、简介</h3><p>这里介绍对go项目进行打包编译生成可执行文件，其实包含参数的传递、目标可执行文件类型、打包对象。</p><h3 id="h-" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">二、使用</h3><p>go项目的编译命令为go build，编译包，生成可执行文件(包含main包),默认生成位置在当前目录下。 (注意不能生成包文件)。如下：</p><pre data-type="codeBlock" text="go build
参数有：
-ldflags：用于编译时设置变量值
-o：指定编译生成的目标文件名
-v:编译时显示包名

另外编译预设变量：
GOOS:指定编译生成可执行文件的运行系统，常用的有：windows、linux、darwin
GOARCH:指定编译生成可执行文件的运行系统架构，常用的有：amd64、arm
"><code>go build
参数有：
<span class="hljs-deletion">-ldflags：用于编译时设置变量值</span>
<span class="hljs-deletion">-o：指定编译生成的目标文件名</span>
<span class="hljs-deletion">-v:编译时显示包名</span>

另外编译预设变量：
GOOS:指定编译生成可执行文件的运行系统，常用的有：windows、linux、darwin
GOARCH:指定编译生成可执行文件的运行系统架构，常用的有：amd64、arm
</code></pre><p>其中参数传递-ldflags的二级参数为：</p><pre data-type="codeBlock" text="-X:设置包中的变量值
-s:去掉符号表，异常时没有文件名或行号信息
-w:去掉DWARF调试信息
"><code><span class="hljs-deletion">-X:设置包中的变量值</span>
<span class="hljs-deletion">-s:去掉符号表，异常时没有文件名或行号信息</span>
<span class="hljs-deletion">-w:去掉DWARF调试信息</span>
</code></pre><h3 id="h-" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">三、示例</h3><h4 id="h-31" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">3.1 带参数编译</h4><p>3.1.1 目标go文件</p><p>这里目标go文件param_main.go我放在with_param目录下。</p><pre data-type="codeBlock" text="package main
import &quot;fmt&quot;

//参数定义，由外部传值
var (
   Env string
   Version string
)
func main() {
   fmt.Printf(&quot;Env:%s Version:%s \n&quot;, Env, Version)
}
"><code><span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> <span class="hljs-string">"fmt"</span>

<span class="hljs-comment">//参数定义，由外部传值</span>
<span class="hljs-keyword">var</span> (
   Env <span class="hljs-type">string</span>
   Version <span class="hljs-type">string</span>
)
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
   fmt.Printf(<span class="hljs-string">"Env:%s Version:%s \n"</span>, Env, Version)
}
</code></pre><pre data-type="codeBlock" text="GOOS=darwin GOARCH=amd64 go build  -o &quot;with_param/param_main&quot; -ldflags &quot;-w -s -X main.Env=test -X main.Version=1.0&quot; with_param/param_main.go
"><code>GOOS<span class="hljs-operator">=</span>darwin GOARCH<span class="hljs-operator">=</span>amd64 go build  <span class="hljs-operator">-</span>o <span class="hljs-string">"with_param/param_main"</span> <span class="hljs-operator">-</span>ldflags <span class="hljs-string">"-w -s -X main.Env=test -X main.Version=1.0"</span> with_param<span class="hljs-operator">/</span>param_main.go
</code></pre><p>运行编译命令后，后成可执行文件param_main，执行文件后，输出：</p><pre data-type="codeBlock" text="Env:test Version:1.0 
"><code>Env:<span class="hljs-built_in">test</span> Version:1.0 
</code></pre><h4 id="h-32" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">3.2 多文件编译</h4><p>在multi目录下新建目标go文件hello.go和multi_main.go，如下：</p><pre data-type="codeBlock" text="package main
func DoHello(name string) {
   println(&quot;hello &quot; + name)
}
"><code><span class="hljs-keyword">package</span> main
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">DoHello</span><span class="hljs-params">(name <span class="hljs-type">string</span>)</span></span> {
   <span class="hljs-built_in">println</span>(<span class="hljs-string">"hello "</span> + name)
}
</code></pre><pre data-type="codeBlock" text="package main
func main() {
   println(&quot;execute main&quot;)
   DoHello(&quot;apple&quot;)
}
"><code><span class="hljs-keyword">package</span> main
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
   <span class="hljs-built_in">println</span>(<span class="hljs-string">"execute main"</span>)
   DoHello(<span class="hljs-string">"apple"</span>)
}
</code></pre><pre data-type="codeBlock" text="GOOS=darwin GOARCH=amd64 go build  -o &quot;multi/multi_main&quot;  multi/multi_main.go multi/hello.go
"><code>GOOS<span class="hljs-operator">=</span>darwin GOARCH<span class="hljs-operator">=</span>amd64 go build  <span class="hljs-operator">-</span>o <span class="hljs-string">"multi/multi_main"</span>  multi<span class="hljs-operator">/</span>multi_main.go multi<span class="hljs-operator">/</span>hello.go
</code></pre><p>运行编译命令后，后成可执行文件multi_main，执行文件后，输出：</p><pre data-type="codeBlock" text="execute main
hello apple
"><code>execute <span class="hljs-selector-tag">main</span>
hello apple
</code></pre><h4 id="h-33-go" class="text-xl font-header !mt-6 !mb-3 first:!mt-0 first:!mb-0">3.3 go项目编译</h4><p>go项目编译直接在项目根目录下编译即可(不需要单独指定编译目录)，如：</p><pre data-type="codeBlock" text="GOOS=darwin GOARCH=amd64 go build  -o &quot;targte_exe&quot; -ldflags &quot;-w -s -X main.Env=test -X main.Version=1.0&quot;
"><code>GOOS<span class="hljs-operator">=</span>darwin GOARCH<span class="hljs-operator">=</span>amd64 go build  <span class="hljs-operator">-</span>o <span class="hljs-string">"targte_exe"</span> <span class="hljs-operator">-</span>ldflags <span class="hljs-string">"-w -s -X main.Env=test -X main.Version=1.0"</span>
</code></pre><p>四、其它 4.1 go install 除了使用go build编译外，还可以使用go install，直接生成库。</p><p>编译包文件(没有main包)后，编译的包放到pkg目录下($GOPATH/pkg) 生成可执行文件(有main包)后，可执行文件放到bin目录下($GOPATH/bin)</p><p>原文链接：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blog.csdn.net/chinabestchina/article/details/109414739">https://blog.csdn.net/chinabestchina/article/details/109414739</a></p>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[React Native的HTTP请求]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/react-native-http</link>
            <guid>pTXPaJ9tn7R4lGLzBreu</guid>
            <pubDate>Tue, 19 Oct 2021 03:10:25 GMT</pubDate>
            <description><![CDATA[前言在一般的手机App中，HTTP请求是一种最常见的获取数据的方式。我们的App要连上广阔的互联网，才能带来一个丰富的世界。那么，在React Native中如何发起HTTP请求呢？发起网络请求要从任意地址获取内容的话，只需简单地将网址作为参数传递给fetch方法即可（fetch这个词本身也就是获取的意思）：fetch('https://mywebsite.com/mydata.json') Fetch还有可选的第二个参数，可以用来定制HTTP请求一些参数。你可以指定header参数，或是指定使用POST方法，又或是提交数据等等，具体方法可以参考文档。 在这里，我们封装一个极简的get请求：var HttpClient={ requestAsync:function(url , callback){ fetch(url) .then((response) => response.json() ) .then((responseJson)=>{ callback.call(this,responseJson); }) .catch((error)=>{ console.error(...]]></description>
            <content:encoded><![CDATA[<h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">前言</h2><p>在一般的手机App中，HTTP请求是一种最常见的获取数据的方式。我们的App要连上广阔的互联网，才能带来一个丰富的世界。那么，在React Native中如何发起HTTP请求呢？</p><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">发起网络请求</h2><p>要从任意地址获取内容的话，只需简单地将网址作为参数传递给fetch方法即可（fetch这个词本身也就是获取的意思）：</p><pre data-type="codeBlock" text="fetch(&apos;https://mywebsite.com/mydata.json&apos;)
"><code><span class="hljs-title function_ invoke__">fetch</span>(<span class="hljs-symbol">'https</span>:<span class="hljs-comment">//mywebsite.com/mydata.json')</span>
</code></pre><p>Fetch还有可选的第二个参数，可以用来定制HTTP请求一些参数。你可以指定header参数，或是指定使用POST方法，又或是提交数据等等，具体方法可以<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://link.jianshu.com?t=http://reactnative.cn/docs/0.43/network.html#content">参考文档</a>。</p><p>在这里，我们封装一个极简的get请求：</p><pre data-type="codeBlock" text="var HttpClient={
    requestAsync:function(url , callback){
      fetch(url)
      .then((response) =&gt; response.json() )
      .then((responseJson)=&gt;{
        callback.call(this,responseJson);
      })
      .catch((error)=&gt;{
        console.error(error);
      });
    }

}

export default HttpClient;
"><code><span class="hljs-keyword">var</span> HttpClient<span class="hljs-operator">=</span>{
    requestAsync:<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">url , callback</span>)</span>{
      fetch(url)
      .then((response) <span class="hljs-operator">=</span><span class="hljs-operator">></span> response.json() )
      .then((responseJson)<span class="hljs-operator">=</span><span class="hljs-operator">></span>{
        callback.<span class="hljs-built_in">call</span>(<span class="hljs-built_in">this</span>,responseJson);
      })
      .catch((<span class="hljs-function"><span class="hljs-keyword">error</span>)=></span>{
        console.error(<span class="hljs-function"><span class="hljs-keyword">error</span>)</span>;
      });
    }

}

export default HttpClient;
</code></pre><p>这个方法非常简单，我们只设计了两个形参（url和回调）。整个fetch方法，十分类似函数式编程的模式。</p><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">一个例子</h2><h3 id="h-" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">需求</h3><p>请求<code>https://facebook.github.io/react-native/movies.json</code>获得它的title字段的信息并显示出来。</p><pre data-type="codeBlock" text="import React, { Component } from &apos;react&apos;;
import {
  AppRegistry,
  Text,
  View,

} from &apos;react-native&apos;;

import HttpClient from &apos;../AwesomeProject/App/widget/HttpClient&apos;

class HelloWorld extends Component {
  render(){
    return (
      &lt;Text&gt;{this.state.title}&lt;/Text&gt;
    )
  }

  constructor(props) {
    super(props);
    this.state={
      title:&apos;loading&apos;,
    };
    var self = this;
    var httpUrl = &apos;https://facebook.github.io/react-native/movies.json&apos;;
    HttpClient.requestAsync(httpUrl , function(responseJson){
      self.setState({
        title:responseJson.title,
        movies:responseJson.movies,
      })
    });
  }
}


AppRegistry.registerComponent(&apos;AwesomeProject&apos;, () =&gt; HelloWorld);
"><code><span class="hljs-keyword">import</span> <span class="hljs-title">React</span>, { <span class="hljs-title">Component</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> {
  <span class="hljs-title">AppRegistry</span>,
  <span class="hljs-title">Text</span>,
  <span class="hljs-title">View</span>,

} <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'react-native'</span>;

<span class="hljs-keyword">import</span> <span class="hljs-title">HttpClient</span> <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'../AwesomeProject/App/widget/HttpClient'</span>

<span class="hljs-title">class</span> <span class="hljs-title">HelloWorld</span> <span class="hljs-title">extends</span> <span class="hljs-title">Component</span> {
  <span class="hljs-title">render</span>(){
    <span class="hljs-title"><span class="hljs-keyword">return</span></span> (
      <span class="hljs-operator">&#x3C;</span><span class="hljs-title">Text</span><span class="hljs-operator">></span>{<span class="hljs-title"><span class="hljs-built_in">this</span></span>.<span class="hljs-title">state</span>.<span class="hljs-title">title</span>}<span class="hljs-operator">&#x3C;</span><span class="hljs-operator">/</span><span class="hljs-title">Text</span><span class="hljs-operator">></span>
    )
  }

  <span class="hljs-title"><span class="hljs-keyword">constructor</span></span>(<span class="hljs-title">props</span>) {
    <span class="hljs-title"><span class="hljs-built_in">super</span></span>(<span class="hljs-title">props</span>);
    <span class="hljs-built_in">this</span>.state={
      title:<span class="hljs-string">'loading'</span>,
    };
    <span class="hljs-keyword">var</span> <span class="hljs-built_in">self</span> <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>;
    <span class="hljs-keyword">var</span> httpUrl <span class="hljs-operator">=</span> <span class="hljs-string">'https://facebook.github.io/react-native/movies.json'</span>;
    HttpClient.requestAsync(httpUrl , <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">responseJson</span>)</span>{
      <span class="hljs-built_in">self</span>.setState({
        title:responseJson.title,
        movies:responseJson.movies,
      })
    });
  }
}


AppRegistry.registerComponent(<span class="hljs-string">'AwesomeProject'</span>, () <span class="hljs-operator">=</span><span class="hljs-operator">></span> HelloWorld);
</code></pre><p>这里我们运用了上一节的state的知识。在HelloWorld的初始化时，我们将<code>this.state.title</code>设为<strong>loading</strong>。然后在HTTP请求的回调中，将responseJson中的title取出，存入this.state.title中。</p><p>由于this.state的值发生改变，render方法会被重新调用。此时this.state.title中的值已经是我们请求回来的数据了，即可渲染成功。</p>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[react-native init XXX遇到的问题]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/react-native-init-xxx</link>
            <guid>11HIWCJT9NI2BSwCfvys</guid>
            <pubDate>Tue, 19 Oct 2021 03:07:11 GMT</pubDate>
            <description><![CDATA[环境：mac os **1.**init 的时候，卡在了cocoapods安装这一步。 解决办法： gem list 把所有涉及到cocoapods的全部uninstall卸载掉 sudo gem uninstall cocoapods -v 1.7.5 sudo gem uninstall cocoapods-xxx ....... 重启mac 最好打开翻墙 然后重新react-native init xxx 估计40分钟-1小时之后跑完 报了一个错会提示‘cd ios && pod install’ 这个时候直接cd到xxx执行 cd ios && pod install 虽然执行完成但是installing DoubleConversion的时候又报了一个错 我又重新执行cd ios && pod install]]></description>
            <content:encoded><![CDATA[<p><strong>环境：mac os</strong></p><p>**1.**init 的时候，卡在了cocoapods安装这一步。</p><p>解决办法：</p><p> gem list</p><p>把所有涉及到cocoapods的全部uninstall卸载掉</p><p>sudo gem uninstall cocoapods -v 1.7.5</p><p>sudo gem uninstall cocoapods-xxx</p><p>.......</p><p>重启mac</p><p>最好打开翻墙</p><p>然后重新react-native init xxx</p><p>估计40分钟-1小时之后跑完</p><p>报了一个错会提示‘cd ios &amp;&amp; pod install’</p><p>这个时候直接cd到xxx执行</p><p>cd ios &amp;&amp; pod install</p><p>虽然执行完成但是installing DoubleConversion的时候又报了一个错</p><p>我又重新执行cd ios &amp;&amp; pod install</p>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
        <item>
            <title><![CDATA[React的生命周期]]></title>
            <link>https://paragraph.com/@eth-mirror-xyz/react</link>
            <guid>lxaBEzDUtC4Y1tOWBCw2</guid>
            <pubDate>Tue, 19 Oct 2021 03:04:11 GMT</pubDate>
            <description><![CDATA[这周开始学习React的生命周期。 React的生命周期从广义上分为三个阶段：挂载、渲染、卸载 因此可以把React的生命周期分为两类：挂载卸载过程和更新过程。 React的生命周期图:1. 挂载卸载过程1.1.constructor()constructor()中完成了React数据的初始化，它接受两个参数：props和context，当想在函数内部使用这两个参数时，需使用super()传入这两个参数。 注意：只要使用了constructor()就必须写super(),否则会导致this指向错误。1.2.componentWillMount()componentWillMount()一般用的比较少，它更多的是在服务端渲染时使用。它代表的过程是组件已经经历了constructor()初始化数据后，但是还未渲染DOM时。1.3.componentDidMount()组件第一次渲染完成，此时dom节点已经生成，可以在这里调用ajax请求，返回数据setState后组件会重新渲染1.4.componentWillUnmount ()在此处完成组件的卸载和数据的销毁。clear你在组建中...]]></description>
            <content:encoded><![CDATA[<p>这周开始学习React的生命周期。</p><p>React的生命周期从广义上分为三个阶段：挂载、渲染、卸载</p><p>因此可以把React的生命周期分为两类：挂载卸载过程和更新过程。 React的生命周期图:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/ae19bd7e5748781bd31f6343c93ed33ce976e6cc96dbbae7912e76f19e5e8b2f.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h1 id="h-1" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">1. 挂载卸载过程</h1><h2 id="h-11constructor" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">1.1.constructor()</h2><p>constructor()中完成了React数据的初始化，它接受两个参数：props和context，当想在函数内部使用这两个参数时，需使用super()传入这两个参数。 注意：只要使用了constructor()就必须写super(),否则会导致this指向错误。</p><h2 id="h-12componentwillmount" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">1.2.componentWillMount()</h2><p>componentWillMount()一般用的比较少，它更多的是在服务端渲染时使用。它代表的过程是组件已经经历了constructor()初始化数据后，但是还未渲染DOM时。</p><h2 id="h-13componentdidmount" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">1.3.componentDidMount()</h2><p>组件第一次渲染完成，此时dom节点已经生成，可以在这里调用ajax请求，返回数据setState后组件会重新渲染</p><h2 id="h-14componentwillunmount" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">1.4.componentWillUnmount ()</h2><p>在此处完成组件的卸载和数据的销毁。</p><ol><li><p>clear你在组建中所有的setTimeout,setInterval</p></li><li><p>移除所有组建中的监听 removeEventListener</p></li><li><p>有时候我们会碰到这个warning:</p></li></ol><pre data-type="codeBlock" text="Can only update a mounted or mounting component. This usually      means you called setState() on an unmounted component. This is a   no-op. Please check the code for the undefined component.
"><code>Can only update a mounted or mounting component. This usually      means you called setState() on an unmounted component. This <span class="hljs-keyword">is</span> a   no<span class="hljs-operator">-</span>op. Please check the code <span class="hljs-keyword">for</span> the undefined component.
</code></pre><p>原因：因为你在组件中的ajax请求返回setState,而你组件销毁的时候，请求还未完成，因此会报warning 解决方法：</p><pre data-type="codeBlock" text="componentDidMount() {
    this.isMount === true
    axios.post().then((res) =&gt; {
    this.isMount &amp;&amp; this.setState({   // 增加条件ismount为true时
      aaa:res
    })
})
}
componentWillUnmount() {
    this.isMount === false
}
"><code>componentDidMount() {
    <span class="hljs-built_in">this</span>.isMount <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-literal">true</span>
    axios.post().then((res) <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
    <span class="hljs-built_in">this</span>.isMount <span class="hljs-operator">&#x26;</span><span class="hljs-operator">&#x26;</span> <span class="hljs-built_in">this</span>.setState({   <span class="hljs-comment">// 增加条件ismount为true时</span>
      aaa:res
    })
})
}
componentWillUnmount() {
    <span class="hljs-built_in">this</span>.isMount <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-literal">false</span>
}
</code></pre><h1 id="h-2" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">2. 更新过程</h1><h2 id="h-21-componentwillreceiveprops-nextprops" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">2.1. componentWillReceiveProps (nextProps)</h2><ol><li><p>在接受父组件改变后的props需要重新渲染组件时用到的比较多</p></li><li><p>接受一个参数nextProps</p></li><li><p>通过对比nextProps和this.props，将nextProps的state为当前组件的state，从而重新渲染组件</p></li></ol><pre data-type="codeBlock" text="  componentWillReceiveProps (nextProps) {
    nextProps.openNotice !== this.props.openNotice&amp;&amp;this.setState({
        openNotice:nextProps.openNotice
    }，() =&gt; {
      console.log(this.state.openNotice:nextProps)
      //将state更新为nextProps,在setState的第二个参数（回调）可以打         印出新的state
  })
}
"><code>  componentWillReceiveProps (nextProps) {
    nextProps.openNotice <span class="hljs-operator">!</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.props.openNotice&#x26;<span class="hljs-operator">&#x26;</span><span class="hljs-built_in">this</span>.setState({
        openNotice:nextProps.openNotice
    }，() <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
      console.log(<span class="hljs-built_in">this</span>.state.openNotice:nextProps)
      <span class="hljs-comment">//将state更新为nextProps,在setState的第二个参数（回调）可以打         印出新的state</span>
  })
}
</code></pre><h2 id="h-22shouldcomponentupdatenextpropsnextstate" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">2.2.shouldComponentUpdate(nextProps,nextState)</h2><ol><li><p>主要用于性能优化(部分更新)</p></li><li><p>唯一用于控制组件重新渲染的生命周期，由于在react中，setState以后，state发生变化，组件会进入重新渲染的流程，在这里return false可以阻止组件的更新</p></li><li><p>因为react父组件的重新渲染会导致其所有子组件的重新渲染，这个时候其实我们是不需要所有子组件都跟着重新渲染的，因此需要在子组件的该生命周期中做判断</p></li></ol><h2 id="h-23componentwillupdate-nextpropsnextstate" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">2.3.componentWillUpdate (nextProps,nextState)</h2><p>shouldComponentUpdate返回true以后，组件进入重新渲染的流程，进入componentWillUpdate,这里同样可以拿到nextProps和nextState。</p><h2 id="h-24componentdidupdateprevpropsprevstate" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">2.4.componentDidUpdate(prevProps,prevState)</h2><p>组件更新完毕后，react只会在第一次初始化成功会进入componentDidmount,之后每次重新渲染后都会进入这个生命周期，这里可以拿到prevProps和prevState，即更新前的props和state。</p><h2 id="h-25render" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">2.5.render()</h2><p>render函数会插入jsx生成的dom结构，react会生成一份虚拟dom树，在每一次组件更新时，在此react会通过其diff算法比较更新前后的新旧DOM树，比较以后，找到最小的有差异的DOM节点，并重新渲染。</p><h1 id="h-3-react" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">3. React新增的生命周期(个人补充)</h1><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/897729a9657528c8e1e9c070a74c9af94915d5e1b0085557668db1867459188e.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-31-getderivedstatefrompropsnextprops-prevstate" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">3.1. getDerivedStateFromProps(nextProps, prevState)</h2><p>代替componentWillReceiveProps()。 老版本中的componentWillReceiveProps()方法判断前后两个 props 是否相同，如果不同再将新的 props 更新到相应的 state 上去。这样做一来会破坏 state 数据的单一数据源，导致组件状态变得不可预测，另一方面也会增加组件的重绘次数。 举个例子:</p><pre data-type="codeBlock" text="// before
componentWillReceiveProps(nextProps) {
  if (nextProps.isLogin !== this.props.isLogin) {
    this.setState({ 
      isLogin: nextProps.isLogin,   
    });
  }
  if (nextProps.isLogin) {
    this.handleClose();
  }
}

// after
static getDerivedStateFromProps(nextProps, prevState) {
  if (nextProps.isLogin !== prevState.isLogin) {
    return {
      isLogin: nextProps.isLogin,
    };
  }
  return null;
}

componentDidUpdate(prevProps, prevState) {
  if (!prevState.isLogin &amp;&amp; this.props.isLogin) {
    this.handleClose();
  }
}
"><code><span class="hljs-comment">// before</span>
componentWillReceiveProps(nextProps) {
  <span class="hljs-keyword">if</span> (nextProps.isLogin <span class="hljs-operator">!</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.props.isLogin) {
    <span class="hljs-built_in">this</span>.setState({ 
      isLogin: nextProps.isLogin,   
    });
  }
  <span class="hljs-keyword">if</span> (nextProps.isLogin) {
    <span class="hljs-built_in">this</span>.handleClose();
  }
}

<span class="hljs-comment">// after</span>
static getDerivedStateFromProps(nextProps, prevState) {
  <span class="hljs-keyword">if</span> (nextProps.isLogin <span class="hljs-operator">!</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> prevState.isLogin) {
    <span class="hljs-keyword">return</span> {
      isLogin: nextProps.isLogin,
    };
  }
  <span class="hljs-keyword">return</span> null;
}

componentDidUpdate(prevProps, prevState) {
  <span class="hljs-keyword">if</span> (<span class="hljs-operator">!</span>prevState.isLogin <span class="hljs-operator">&#x26;</span><span class="hljs-operator">&#x26;</span> <span class="hljs-built_in">this</span>.props.isLogin) {
    <span class="hljs-built_in">this</span>.handleClose();
  }
}
</code></pre><p>这两者最大的不同就是: 在 componentWillReceiveProps 中，我们一般会做以下两件事，一是根据 props 来更新 state，二是触发一些回调，如动画或页面跳转等。</p><ol><li><p>在老版本的 React 中，这两件事我们都需要在 componentWillReceiveProps 中去做。</p></li><li><p>而在新版本中，官方将更新 state 与触发回调重新分配到了 getDerivedStateFromProps 与 componentDidUpdate 中，使得组件整体的更新逻辑更为清晰。而且在getDerivedStateFromProps 中还禁止了组件去访问 this.props，强制让开发者去比较 nextProps 与 prevState 中的值，以确保当开发者用到 getDerivedStateFromProps 这个生命周期函数时，就是在根据当前的 props 来更新组件的 state，而不是去做其他一些让组件自身状态变得更加不可预测的事情。</p></li></ol><h2 id="h-32-getsnapshotbeforeupdateprevprops-prevstate" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">3.2. getSnapshotBeforeUpdate(prevProps, prevState)</h2><p>代替componentWillUpdate。 常见的 componentWillUpdate 的用例是在组件更新前，读取当前某个 DOM 元素的状态，并在 componentDidUpdate 中进行相应的处理。 这两者的区别在于：</p><ul><li><p>在 React 开启异步渲染模式后，在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同，这就导致在componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的，因为这时的值很有可能已经失效了。</p></li><li><p>getSnapshotBeforeUpdate 会在最终的 render 之前被调用，也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。此生命周期返回的任何值都将作为参数传递给componentDidUpdate（）。</p></li></ul>]]></content:encoded>
            <author>eth-mirror-xyz@newsletter.paragraph.com (eth.mirror.xyz)</author>
        </item>
    </channel>
</rss>