滿滿的愛

文章 评论 浏览 28

滿滿的愛 2025-02-20 22:42:41

好吧,对于这个问题,循环将有助于游戏更具动态性,使玩家能够直到玩家退出游戏为止。我还将您的代码的部分集成到了该修订后的部分中。希望这会有所帮助

import random as r
game = True
print("Want to play Rock Paper Scissors??")
question1=input("Y/N: ").lower()
options = ['Rock', 'Paper', "Scissors"]
if question1=='y':
    print('Perfect but first')
    print('Do you know how to play??')
    question2=input("Y/N: ").lower()
    if question2=='y':
                print('Ok lets get started!')
    elif question2=='n':
        print('Pick 1 of the 3 options to battle my option')
        print('Rock beats scissors')
        print("Paper beats rock")
        print('Scissors beats paper')   
    while game:
        pick = input('Take your pick(rock,paper or scissors):  ')
        if pick.capitalize() in options:
            Ai = r.choice(options)
            if (pick.lower()=="scissors"and Ai.lower()=="rock") or (pick.lower()=="paper" and Ai.lower()=="scissors") or (pick.lower()=="rock" and Ai.lower()=="paper"): #this is the rules for Ai vs user input(in this case Ai wins)
                print("you lose, "+ Ai +" beats "+ pick )
            elif (pick.lower()=="rock"and Ai.lower()=="scissors") or (pick.lower()=="scissors" and Ai.lower()=="paper") or (pick.lower()=="paper" and Ai.lower()=="rock"): #this is the rules for Ai vs user input(in this case player wins)
                print("you win, "+ pick +" beats "+ Ai )
            else: # in rare cases where both are the same 
                print("it's a tie, "+pick +" draws with " +Ai)
        elif pick.lower() not in options: #if the user input is not found
            print("option was not found")
        cont = input("do you want to continue [Y/N]: ")
        if cont.lower() =="n": #opting out(user quitting statement)
            game = False
        else:
            continue
            
elif question1== 'n':
    print('Alright good bye')

Well, for this question a while loop would help the game be more dynamic, allowing the player to until the player opt-out of the game. I also integrated parts of your code into this revised one. Hope this helps

import random as r
game = True
print("Want to play Rock Paper Scissors??")
question1=input("Y/N: ").lower()
options = ['Rock', 'Paper', "Scissors"]
if question1=='y':
    print('Perfect but first')
    print('Do you know how to play??')
    question2=input("Y/N: ").lower()
    if question2=='y':
                print('Ok lets get started!')
    elif question2=='n':
        print('Pick 1 of the 3 options to battle my option')
        print('Rock beats scissors')
        print("Paper beats rock")
        print('Scissors beats paper')   
    while game:
        pick = input('Take your pick(rock,paper or scissors):  ')
        if pick.capitalize() in options:
            Ai = r.choice(options)
            if (pick.lower()=="scissors"and Ai.lower()=="rock") or (pick.lower()=="paper" and Ai.lower()=="scissors") or (pick.lower()=="rock" and Ai.lower()=="paper"): #this is the rules for Ai vs user input(in this case Ai wins)
                print("you lose, "+ Ai +" beats "+ pick )
            elif (pick.lower()=="rock"and Ai.lower()=="scissors") or (pick.lower()=="scissors" and Ai.lower()=="paper") or (pick.lower()=="paper" and Ai.lower()=="rock"): #this is the rules for Ai vs user input(in this case player wins)
                print("you win, "+ pick +" beats "+ Ai )
            else: # in rare cases where both are the same 
                print("it's a tie, "+pick +" draws with " +Ai)
        elif pick.lower() not in options: #if the user input is not found
            print("option was not found")
        cont = input("do you want to continue [Y/N]: ")
        if cont.lower() =="n": #opting out(user quitting statement)
            game = False
        else:
            continue
            
elif question1== 'n':
    print('Alright good bye')

我需要在此岩纸仪代码中做什么?

滿滿的愛 2025-02-20 21:24:30

Adobe非常清楚地表明,您不能在服务器应用程序中使用Indesign Desktop应用程序,

https://www.adobe.com/products/indesignserver/faq.html

如果我使用Indesign的桌面版本作为服务器引擎?

是的,Indesign桌面版本的EULA不允许
它用作服务器引擎来为自动发布解决方案供电
由他人共享。使用Indesign桌面进行脚本限制在于
购买了订阅的指定用户。

Adobe makes it super clear that you cannot use InDesign desktop app in a server application,

https://www.adobe.com/products/indesignserver/faq.html

Will I violate the terms of the End-User License Agreement (EULA) if I use the desktop version of InDesign as a server engine?

Yes, the EULA for the desktop version of InDesign does not allow for
its use as a server engine to power an automated publishing solution
shared by others. Use of InDesign desktop for scripting is limited to
the named user that has purchased the subscription.

如何使用C#从Indesign文档中读取文本帧中的内容?

滿滿的愛 2025-02-20 19:44:10

由于您使用的是颤动,因此您需要存储要重新渲染的值已更新,然后在 build 方法中从那里渲染。

我建议在

Since you're using Flutter, you'll need to store the value you want to re-render in the State of a stateful widget, call setState() when the value is updated, and then render it from there in your build method.

I recommend checking the documentation on StatefulWidget for an example of this, and more explanation than I can ever repeat here.

在没有重新加载模拟器的情况下更新操作中的playname

滿滿的愛 2025-02-20 15:06:48

添加“定制”是请求对象 req.customid 应该有效。

Adding "customId" is request object req.customId should work.

Nest JS将动态对象从控制器传递到服务,而无需使用参数

滿滿的愛 2025-02-20 10:38:19

通常,任何现代编译器都应为诸如此类的琐碎示例生成相同的机器代码。只需观看任何编译器(例如GCC)的拆卸,启用优化并亲自查看即可。 :

#include <stdbool.h>

int example1 (bool something)
{
  if(something == true) 
    return -1;
  else 
    return 0;
}

int example2 (bool something)
{
  if(something == true) 
    return -1;
  return 0;
}

int example3 (bool something)
{
  return something==true ? -1 : 0;
}

int example4 (bool something)
{
  for(int i=something; i!=false; i++)
  {
    if(i)
      return -1;
  }
  return 0;
}

https://godbolt.org/z/1kxxxsbj9s

示例 同一机器代码,甚至是人为的示例4:

    movzx   eax, dil
    neg     eax
    ret

也就是说,抓住输入参数并将其替换为两者的补充( neg ),意思是 1 - &gt; -1 0 - &gt; 0

优化器还没有生成任何分支(条件执行路径),这会使所有高端CPU上的代码较慢。

因此,使用哪种形式主要是一种样式问题。各种安全标准(ISO 61508,ISO 26262,MISRA C等)在一个功能中倾向于在多个返回上皱眉,因此,如果您关心的话, xpecond> example3 可能可能实际上是最好的。

Generally any modern compiler should generate the same machine code for trivial examples such as this. Just watch the disassembly from any compiler such as gcc, enable optimizations and see for yourself. Examples:

#include <stdbool.h>

int example1 (bool something)
{
  if(something == true) 
    return -1;
  else 
    return 0;
}

int example2 (bool something)
{
  if(something == true) 
    return -1;
  return 0;
}

int example3 (bool something)
{
  return something==true ? -1 : 0;
}

int example4 (bool something)
{
  for(int i=something; i!=false; i++)
  {
    if(i)
      return -1;
  }
  return 0;
}

https://godbolt.org/z/1Kxxsbj9s

All of these examples boil down to the very same machine code, even the contrived example4 one:

    movzx   eax, dil
    neg     eax
    ret

That is, grab the input parameter and replace it with it's two's complement (neg), meaning either 1 -> -1 or 0 -> 0.

The optimizer also didn't generate any branch (conditional execution paths) which would have made the code slower on all high-end CPUs.

So which form to use is mostly a matter of style. Various safety standards (ISO 61508, ISO 26262, MISRA C etc) tend to quite subjectively frown at multiple return in a single function, so if you care about that, example3 might actually be the best one.

删除C中的其他语句是否更有效?

滿滿的愛 2025-02-19 23:07:11

尝试此代码。它不依赖 QVBoxLayout ,但基本上与此布局相同。它隐藏了该地区以外的儿童小部件。没有部分可见的小部件。

from PyQt5 import QtWidgets

class Container(QtWidgets.QWidget):
    _spacing = 5

    def __init__(self, parent=None):
        super().__init__(parent)
        y = self._spacing
        for i in range(40):
            button = QtWidgets.QPushButton("Button" + str(i + 1), self)
            button.move(self._spacing, y)
            y += button.sizeHint().height() + self._spacing

    def resizeEvent(self, event):
        super().resizeEvent(event)
        for child in self.children():
           if isinstance(child, QtWidgets.QWidget):
               child.resize(self.width() - 2 * self._spacing, child.height())
               child.setVisible(child.geometry().bottom() < self.height())


app = QtWidgets.QApplication([])
w = Container()
w.resize(500, 500)
w.show()
app.exec_()

请注意,实际上不是添加 nor 动态删除窗口小部件,这将是更多的代码,并且可能非常取决于您的特定用例。此外,感觉是一种过早的优化。除非您确实需要它,否则请不要这样做。

更新:
我尝试了上面的代码,并提出了一些改进。我特别想让它对儿童小部件的变化做出反应。问题在于,如果子小部件更改其大小,则必须重新使用父容器。上面的代码不会以任何方式做出反应。为了使其响应迅速,我们需要对 layoutrequest 事件做出反应。请注意,在下面的代码中,我创建了三种类型的按钮 - 一个按钮添加了一条线,另一个可以增加字体大小,而另一个则减小了字体大小。

from PyQt5 import QtCore, QtWidgets

def changeFontSize(increment):
    font = QtWidgets.QApplication.font()
    font.setPointSize(font.pointSize() + increment)
    QtWidgets.QApplication.setFont(font)

class Container(QtWidgets.QWidget):
    _spacing = 5
    _children = []  # maintains the order of creation unlike children()

    def __init__(self, parent=None):
        super().__init__(parent)
        for i in range(100):
            child = QtWidgets.QPushButton(self)
            child.installEventFilter(self)
            # these are just to test various changes in child widget itself to force relayout
            r = i % 3
            if r == 0:
                text = "New line"
                onClicked = lambda state, w=child: w.setText(w.text() + "\nclicked")
            elif r == 1:
                text = "Bigger font"
                onClicked = lambda: changeFontSize(1)
            elif r == 2:
                text = "Smaller font"
                onClicked = lambda: changeFontSize(-1)

            child.setText(text)
            child.clicked.connect(onClicked)
            self._children.append(child)

    def resizeEvent(self, event):
        super().resizeEvent(event)    
        self._relayout() 
           
    def event(self, event):
        if event.type() == QtCore.QEvent.LayoutRequest:
            self._relayout()
            
        return super().event(event)

    def _relayout(self):
        y = self._spacing
        for child in self._children:
            h = child.sizeHint().height()
            child.move(self._spacing, y)
            child.resize(self.width() - 2 * self._spacing, h)
            y += h + self._spacing
            child.setVisible(y < self.height()) 

app = QtWidgets.QApplication([])
w = Container()
w.resize(500, 500)
w.show()
app.exec_()

此代码令人满意,但是并不完美。我已经观察到,当重新划分容器并且某些儿童小部件会更改其可见性状态时,重新涂层会再次调用。这不是需要的,但是我没有发现如何防止它。

也许有更好的方法...

Try this code. It does not rely on QVBoxLayout but it basically does the same as this layout. It hides the child widgets which are outside of the area. There are no partially visible widgets.

from PyQt5 import QtWidgets

class Container(QtWidgets.QWidget):
    _spacing = 5

    def __init__(self, parent=None):
        super().__init__(parent)
        y = self._spacing
        for i in range(40):
            button = QtWidgets.QPushButton("Button" + str(i + 1), self)
            button.move(self._spacing, y)
            y += button.sizeHint().height() + self._spacing

    def resizeEvent(self, event):
        super().resizeEvent(event)
        for child in self.children():
           if isinstance(child, QtWidgets.QWidget):
               child.resize(self.width() - 2 * self._spacing, child.height())
               child.setVisible(child.geometry().bottom() < self.height())


app = QtWidgets.QApplication([])
w = Container()
w.resize(500, 500)
w.show()
app.exec_()

Note that is in fact does not add nor remove widgets dynamically, this would be much more code and it would probably be very depending on your specific use case. Moreover it feels as a premature optimization. Unless you really need it, do not do it.

UPDATE:
I experimented with the code above and proposed some improvements. I especially wanted to make it responsive to changes in child widgets. The problem is that if the child widget changes it size, the parent container must be re-layouted. The code above does not react in any way. To make it responsive, we need to react to LayoutRequest event. Note that in the code below, I have created three types of buttons - one add a line to itself, other increases font size, and yet another decreases font size.

from PyQt5 import QtCore, QtWidgets

def changeFontSize(increment):
    font = QtWidgets.QApplication.font()
    font.setPointSize(font.pointSize() + increment)
    QtWidgets.QApplication.setFont(font)

class Container(QtWidgets.QWidget):
    _spacing = 5
    _children = []  # maintains the order of creation unlike children()

    def __init__(self, parent=None):
        super().__init__(parent)
        for i in range(100):
            child = QtWidgets.QPushButton(self)
            child.installEventFilter(self)
            # these are just to test various changes in child widget itself to force relayout
            r = i % 3
            if r == 0:
                text = "New line"
                onClicked = lambda state, w=child: w.setText(w.text() + "\nclicked")
            elif r == 1:
                text = "Bigger font"
                onClicked = lambda: changeFontSize(1)
            elif r == 2:
                text = "Smaller font"
                onClicked = lambda: changeFontSize(-1)

            child.setText(text)
            child.clicked.connect(onClicked)
            self._children.append(child)

    def resizeEvent(self, event):
        super().resizeEvent(event)    
        self._relayout() 
           
    def event(self, event):
        if event.type() == QtCore.QEvent.LayoutRequest:
            self._relayout()
            
        return super().event(event)

    def _relayout(self):
        y = self._spacing
        for child in self._children:
            h = child.sizeHint().height()
            child.move(self._spacing, y)
            child.resize(self.width() - 2 * self._spacing, h)
            y += h + self._spacing
            child.setVisible(y < self.height()) 

app = QtWidgets.QApplication([])
w = Container()
w.resize(500, 500)
w.show()
app.exec_()

This code is satisfactory, however it is not perfect. I have observed that when the container is being re-layouted and some of the child widgets will change its visibility state, re-layouting is called again. This is not needed but I have not discovered how to prevent it.

Maybe there is some better way...

如何避免过度包装非质量QT布局?

滿滿的愛 2025-02-19 16:58:09

请将helpers.py也复制到工作目录中。

COPY helpers.py .

或者

ADD . /app 
#This will add all files in the current local dir to /app

Please copy the helpers.py as well into the working directory.

COPY helpers.py .

OR

ADD . /app 
#This will add all files in the current local dir to /app

如何将Python文件导入另一个Python文件中,以便在Docker中起作用?

滿滿的愛 2025-02-19 04:45:29

在您的动态上,请检查某些内容,并确保报告在当前记录上运行

“

如果在所有相关记录的运行中设置了它,请在您的解决方案中删除报告并再次添加(最好是用一个新名称只需在名称的末尾添加_v2或_v3并再次设置。我相信动态CRM有一个错误。

On your Dynamic-CRM check something and make sure the report is running on Current Record

enter image description here

if it is set on run for all related records Simply delete the report in your solution and add it again (preferably with a new name just add an _V2 or _V3 at the end of the name and set it up again.) this should do the trick as it did for me. I believe there is a bug in Dynamic CRM.

预过滤Microsoft Dynamic 365 SSRS未在打开的记录上过滤基础

滿滿的愛 2025-02-19 03:04:42

简而言之:

import pandas as pd
# ...
pd.set_option('mode.chained_assignment', None)

Just simply:

import pandas as pd
# ...
pd.set_option('mode.chained_assignment', None)

如何处理熊猫的withcopywarning

滿滿的愛 2025-02-18 23:49:05

您应该使用Packer.toblob使用第三个选项,并在Promise Packer.toblob(即将解决)后才调用一次zip.generateasync。
zip存档的哑光型应该是应用/zip(默认值,您不能传递此参数)

Packer.toBlob(doc).then(blob => {
  word?.file(
    `${forword.headerName}.rtf`,
    blob,
    { binary: true }
  );

  zip.generateAsync({type:"blob",compression: "DEFLATE" })
    .then(content => FileSaver.saveAs(content, `examples.zip`));
);

You should use the 3rd option with Packer.toBlob and call zip.generateAsync only ONCE right after promise Packer.toBlob will be resolved.
Mime-type of zip archive should be application/zip (it's default value, you can just not pass this parameter)

Packer.toBlob(doc).then(blob => {
  word?.file(
    `${forword.headerName}.rtf`,
    blob,
    { binary: true }
  );

  zip.generateAsync({type:"blob",compression: "DEFLATE" })
    .then(content => FileSaver.saveAs(content, `examples.zip`));
);

如何将DOCX放入JSZIP

滿滿的愛 2025-02-18 17:13:08

我认为这仅仅是因为数据框中有列 x ,而 filter 是使用此 x 而不是参数 x 到您的在线功能。如果您在函数声明中将变量名从 x 更改为 z ,我认为它有效。请参阅下面。

尽管如此,我认为这是对 iris |&gt的基本管道的罢工。滤波器(完整。Cases(_))引发错误。 _ 只能用作管道函数的命名参数,并且不能用作可以用作变量的限制?

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

complete_data_native_wrong <- function(data){
  res <- data |>  (\(z) filter(z, complete.cases(z)))()  # change to z
  return(res)
}

df <- structure(
  list(x = c(1, 2, NA, 4), 
       y = c(NA, NA, 3, 4)), 
  class = c("tbl_df", 
            "tbl", "data.frame"), 
  row.names = c(NA, -4L)
)

df |> complete_data_native_wrong()
#> # A tibble: 1 × 2
#>       x     y
#>   <dbl> <dbl>
#> 1     4     4

I think it's simply because there is a column x in the data frame, and filter is using this x instead of the argument x to your in-line function. If you change the variable name from x to z in your function declaration, I think it works. Please see below.

Still, I think it's a strike against the base pipe that iris |> filter(complete.cases(_)) throws an error. Is the limitation that _ can only be used as a named argument to the piped function, and can't be used as a variable like . can?

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

complete_data_native_wrong <- function(data){
  res <- data |>  (\(z) filter(z, complete.cases(z)))()  # change to z
  return(res)
}

df <- structure(
  list(x = c(1, 2, NA, 4), 
       y = c(NA, NA, 3, 4)), 
  class = c("tbl_df", 
            "tbl", "data.frame"), 
  row.names = c(NA, -4L)
)

df |> complete_data_native_wrong()
#> # A tibble: 1 × 2
#>       x     y
#>   <dbl> <dbl>
#> 1     4     4

Created on 2022-06-29 by the reprex package (v2.0.1)

R:从Magrittr到本地管道的过渡和功能的翻译

滿滿的愛 2025-02-18 06:52:49

它将按照您想要的 来工作

 const checkIfUserThere = () => {
   let newUser = "[email protected]";
    for (const data of users) {
     if (data.email === newUser) {
       return true;
        }
    }

     return false;
  };

It will work as you want

 const checkIfUserThere = () => {
   let newUser = "[email protected]";
    for (const data of users) {
     if (data.email === newUser) {
       return true;
        }
    }

     return false;
  };

即使数组中存在数据,返回false

滿滿的愛 2025-02-18 03:36:21
var parentDiv = document.getElementsByClassName("catColumn")[0];
parentDiv.addEventListener("click",function(e){
let current= e.target;

var collapse = document.getElementsByClassName("collapsible");
let toExpand = !current.nextElementSibling.style.maxHeight ;
for (let i = 0; i < collapse.length; i++) {          
    var content = collapse[i].nextElementSibling;
    if (content.style.maxHeight) {
      content.style.maxHeight = null;
      collapse[i].classList.toggle("activeCollapse");
    }
  }
  let toToggle = current.nextElementSibling;
   if(toExpand ){
    toToggle.style.maxHeight = content.scrollHeight + "px";
     current.classList.toggle("activeCollapse");
    }
  
});
.catColumn {
  width: 400px;
  margin: 0 auto;
}

.collapsible {
  width: 100%;
  padding: 14px 8px;
  margin-top: 10px;
  color: #5a2e0f;
  background-color: #fff;
  border: 1px solid #c1bfbf;
  outline: none;
  border-radius: 6px;
}

.collapsible:hover {
  background-color: #efdac6;
}

.collapsible:after {
  float: right;
  content: '\002B';
  color: #5a2e0f;
  font-size: 1.8em;
  margin-left: 5px;
  cursor: pointer;
  line-height: 26px;
}

.activeCollapse {
  background-color: #efdac6;
  border-radius: 0;
  border-bottom: 0px;
}

.activeCollapse:after {
  content: "\2212";
}


/**/

ul.subcats {
  width: 100%;
  max-height: 0;
  transition: max-height 1s ease-out;
  overflow: hidden;
  font-size: 13px;
}

ul.subcats li {
  padding: 12px;
}
<div class="catColumn">
  <div class="collapsible">cat1</div>
  <ul class="subcats">
    <li>subcat1</li>
    <li>subcat2</li>
  </ul>
  <div class="collapsible">cat2</div>
  <ul class="subcats">
    <li>subcat3</li>
    <li>subcat4</li>
  </ul>
</div>

var parentDiv = document.getElementsByClassName("catColumn")[0];
parentDiv.addEventListener("click",function(e){
let current= e.target;

var collapse = document.getElementsByClassName("collapsible");
let toExpand = !current.nextElementSibling.style.maxHeight ;
for (let i = 0; i < collapse.length; i++) {          
    var content = collapse[i].nextElementSibling;
    if (content.style.maxHeight) {
      content.style.maxHeight = null;
      collapse[i].classList.toggle("activeCollapse");
    }
  }
  let toToggle = current.nextElementSibling;
   if(toExpand ){
    toToggle.style.maxHeight = content.scrollHeight + "px";
     current.classList.toggle("activeCollapse");
    }
  
});
.catColumn {
  width: 400px;
  margin: 0 auto;
}

.collapsible {
  width: 100%;
  padding: 14px 8px;
  margin-top: 10px;
  color: #5a2e0f;
  background-color: #fff;
  border: 1px solid #c1bfbf;
  outline: none;
  border-radius: 6px;
}

.collapsible:hover {
  background-color: #efdac6;
}

.collapsible:after {
  float: right;
  content: '\002B';
  color: #5a2e0f;
  font-size: 1.8em;
  margin-left: 5px;
  cursor: pointer;
  line-height: 26px;
}

.activeCollapse {
  background-color: #efdac6;
  border-radius: 0;
  border-bottom: 0px;
}

.activeCollapse:after {
  content: "\2212";
}


/**/

ul.subcats {
  width: 100%;
  max-height: 0;
  transition: max-height 1s ease-out;
  overflow: hidden;
  font-size: 13px;
}

ul.subcats li {
  padding: 12px;
}
<div class="catColumn">
  <div class="collapsible">cat1</div>
  <ul class="subcats">
    <li>subcat1</li>
    <li>subcat2</li>
  </ul>
  <div class="collapsible">cat2</div>
  <ul class="subcats">
    <li>subcat3</li>
    <li>subcat4</li>
  </ul>
</div>

JavaScript改善崩溃元素

滿滿的愛 2025-02-18 03:34:08

除@TJ Crowder的答案外,

您的示例项目还以&lt; strictmode&gt; 运行,因此React将在 dev 模式下两次运行一个组件来验证事物。要了解问题,首先让我们从 index.js 暂时删除&lt; scrictmode

基本上,我需要的是usecallbacks,因为普通组件没有
通过相同的道具重新渲染。那我想念什么?备忘录
有帮助以优化?

通过使用备忘录,您告诉对帐算法,如果道具相同,请不要下降并再次渲染子组件。但是在没有备忘录的普通组件中,对帐算法将穿越树并调用您的子组件(因为那是算法应该做的)。一旦完成遍历(渲染),React将把更改与DOM冲洗。由于没有任何更改会对DOM进行。但是,使用备忘您正在加快遍历过程。


注:

在React中,'渲染'并不意味着更新DOM元素。渲染是指调用您的函数组件或component.render()方法。这不是一个昂贵的过程,因此React会这样做,但是React不会盲目地将变化冲洗给DOM。您可以通过打开检查元素来验证这一点。当您展开检查元素时,单击按钮,您将不会看到任何更改(创建/删除DOM元素上的紫色颜色亮点的动画)会发生。
通过使用备忘录,您可以手动停止渲染()并移至兄弟姐妹(如果有)继续重新渲染而不是进入子元素。这也是为什么您不能使用 console.log 实际测试React应用程序的性能。
console.log 是副作用。严格地告诉您不要为渲染阶段(功能主体的最高级别)添加副作用。 您需要使用使用


要处理副作用, 重新加载预览,我们将在控制台上获取以下日志,

对于此组件,

    <div className="App">
      ref: <Child txt="ref" fn={handlerOfWhoKnows} />
      useCB: <Child txt="useCb" fn={useCallback(handlerOfWhoKnows, [])} />
      memo: <MemoChild txt="memo" fn={handlerOfWhoKnows} />
      memo + useCB: <MemoChild txt="memo+useCb" fn={useCallback(handlerOfWhoKnows, [])} />
    </div>

它将在MOUTE上登录

ref rendered!
useCb rendered! 
memo rendered! 
memo+useCb rendered!

ref rendered! 
useCb rendered! 
memo rendered! 
memo+useCb rendered! 

1。在坐骑上登录两次,

这是您看到每个日志打印两次的原因,您使用 pers a 使用> 在您的&lt; child/&gt; 组件中。

  useEffect(() => {
    setState((state) => state + 1);
  }, [fn]);

由于触发了状态变化,因此第二次也将在第二次运行&lt; child /&gt; < /code>。它与道具无关。如果我们删除此 useffect ,现在您可以将安装log看到为

ref rendered! 
useCb rendered! 
memo rendered! 
memo+useCb rendered! 

单击按钮。

2。在孩子中删除 strictmmode stricteffect 后 ,然后单击按钮。这次将打印

ref rendered! // rendered due to the prop changed
useCb rendered! // rendered due to the prop changed
memo rendered! // rendered due to the prop changed

这次您可以看到的日志, MEMO+USECB 未打印。下一个问题是为什么,

3。为什么在第二步中呈现备忘录!

这是因为您没有回忆 fn ,因此每次渲染时都会重新创建。因此,道具变更 - &gt;组件重新渲染,

因此,

const handlerOfWhoKnows = useCallback(() => {}, []);

<MemoChild txt="memo" fn={handlerOfWhoKnows} />

随着更改,代码应该看起来像是

  const handlerOfWhoKnows = useCallback(() => {}, []);

  return (
    <div className="App">
      ref: <Child txt="ref" fn={handlerOfWhoKnows} />
      useCB: <Child txt="useCb" fn={handlerOfWhoKnows} />
      memo: <MemoChild txt="memo" fn={handlerOfWhoKnows} />
      memo + useCB: <MemoChild txt="memo+useCb" fn={handlerOfWhoKnows} />
    </div>
  );

现在,当我们单击按钮时,我们只会看到

ref rendered! 
useCb rendered! 

,所以您的问题的答案,

何时备忘录以优化?

如果道具相同,备忘录有助于手动停止进一步的渲染。一旦看到备忘录,对帐算法将停止遍历,道具相同。它将完成渲染树,否则将继续渲染兄弟姐妹。

同样,使用备忘录太多也可能导致性能问题,因为备忘它会做一些过程来弄清楚是否渲染孩子。使用 usecallback usememo 仔细。

Additional to the @T.J Crowder's answer,

Your sample project runs in <StrictMode> so React will run a component twice in dev mode to validate things. To understand the issue, first lets remove <ScrictMode temporally from the index.js

Basically, useCallbacks is all I need, as a normal component doesn't
get re-rendered with same props. Then, what I'm I missing? When memo
comes in help to optimize?

By using memo you are telling the reconciliation algorithm to NOT to go down and render the Child component again if the props are same. But in a normal component without memo, the reconciliation algorithm will traverse through the tree and call your child component ( because that's what algorithm supposed to do ). Once the traversing(rendering) is done, react will flush the changes to the DOM. As there's no changes will be committed to the DOM. but using memo you are speed up the traversing process.


NOTE:

In React, 'render' doesn't mean updating the DOM elements. rendering mean calling your function component or Component.render() method. This is not an expensive process so React will do it but React won't blindly flush the changes to the DOM. You can validate this by open the inspect element. When you expand the inspect element, click the button, you won't see any changes(create/delete animation with purple color highlight on dom elements) happens.
By using memo you manually stop the render() and move to the sibling element ( if available ) to continue re render instead of going into the child element. This is also why you cannot use console.log to actually test the performance of the react app.
console.log is a side effect. React strictly telling you to not add side effect to the render phase ( top level of your function body ). To handle side effects you need to use useEffect.


Now lets see the issues in your code, Based on your sandbox code, after removing <StrictMode> and reload the preview, we will get the following logs on the console,

For this component,

    <div className="App">
      ref: <Child txt="ref" fn={handlerOfWhoKnows} />
      useCB: <Child txt="useCb" fn={useCallback(handlerOfWhoKnows, [])} />
      memo: <MemoChild txt="memo" fn={handlerOfWhoKnows} />
      memo + useCB: <MemoChild txt="memo+useCb" fn={useCallback(handlerOfWhoKnows, [])} />
    </div>

It will log following on mount,

ref rendered!
useCb rendered! 
memo rendered! 
memo+useCb rendered!

ref rendered! 
useCb rendered! 
memo rendered! 
memo+useCb rendered! 

1. log print twice on mount

The reason why you see each logs print twice is, you use a useEffect inside your <Child/> component.

  useEffect(() => {
    setState((state) => state + 1);
  }, [fn]);

Since the state change triggered, React will re run the <Child /> for the 2nd time as well. It has nothing to do with the props. If we remove this useEffect, now you can see the mount log as,

ref rendered! 
useCb rendered! 
memo rendered! 
memo+useCb rendered! 

2. Clicking the button

After remove the StrictMode and useEffect in the child, and click the button. This time the log will print

ref rendered! // rendered due to the prop changed
useCb rendered! // rendered due to the prop changed
memo rendered! // rendered due to the prop changed

This time you can see, memo+useCb is not printed. The next issue is why,

3. Why memo rendered! in 2nd step.

This is because you didn't memoized the fn so it will recreate everytime when rendering. So props change -> component re render

So code should be,

const handlerOfWhoKnows = useCallback(() => {}, []);

<MemoChild txt="memo" fn={handlerOfWhoKnows} />

Now with the changes, the component will looks like,

  const handlerOfWhoKnows = useCallback(() => {}, []);

  return (
    <div className="App">
      ref: <Child txt="ref" fn={handlerOfWhoKnows} />
      useCB: <Child txt="useCb" fn={handlerOfWhoKnows} />
      memo: <MemoChild txt="memo" fn={handlerOfWhoKnows} />
      memo + useCB: <MemoChild txt="memo+useCb" fn={handlerOfWhoKnows} />
    </div>
  );

Now when we click the button, we will only see,

ref rendered! 
useCb rendered! 

So the answer for your question,

When memo comes in help to optimize?

memo helps to manually stop the further rendering if the props are same. Reconciliation algorithm will stop traversing once it see a memo and props are same. It will complete the rendering the tree or it will continue to render the sibling element.

Also using the memo too much can lead to performance issues as well because memo it self does some process to figure out whether to render the child or not. Use useCallback and useMemo carefully.

React.Memo与UseCallback一起使用

滿滿的愛 2025-02-18 03:23:22

您的会话导入是错误的。用 android.se.omapi.session javax.mail.mail.session 替换导入。如果这会导致其他问题,因为您需要两个导入,那么对于其中一个就需要使用完全合格的名称。例如:

javax.mail.Session session = javax.mail.Session.getDefaultInstance(properties, null);

另一个问题是 uri 参数。没有 Mimemessage 构造函数,它可以采用 uri uri 参数。我认为您有现有消息作为文件,并且想从中阅读。您需要将 uri 转换为 inputstream 。我在。我会看看您是否可以完全摆脱 uri 参数,并用 inputStream 或可以将其转换为 InputStream 的东西替换。 。

Your Session import is the wrong one. Replace the import for android.se.omapi.Session with javax.mail.Session. If that causes other issues, because you need both imports, then for one of them you to use the fully qualified name. For instance:

javax.mail.Session session = javax.mail.Session.getDefaultInstance(properties, null);

The other issue is the Uri argument. There is no MimeMessage constructor that takes a URI or Uri argument. I assume that you have an existing message as a file and want to read from it. You'd need to convert the Uri to an InputStream. I couldn't find anything for that in https://developer.android.com/reference/android/net/Uri. I'd see if you can get rid of the Uri argument completely and replace it with an InputStream or something that can be converted to an InputStream.

getDefaultInstance和javax.mail.session的问题,java.io.inputstream

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

更多

友情链接

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文