我正在阅读关于功能更新的React Hook留档,请参阅以下引用:
“”和“-”按钮使用函数形式,因为更新的值基于以前的值
但是我看不出需要功能更新的目的是什么,它们和直接使用旧状态计算新状态有什么区别。
为什么React-useState钩子的更新程序函数需要函数更新表单?在哪些示例中,我们可以清楚地看到差异(因此使用直接更新会导致错误)?
例如,如果我从文档中更改此示例
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
</>
);
}
要直接更新count
:
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</>
);
}
我看不到行为上的任何差异,也无法想象计数不会被更新(或者不会是最新的)。因为无论何时更改计数,都将调用onClick
的新闭包,以捕获最新的count
。
我已经回答了一个类似的问题,因为这是一个我不知道的经典问题,所以我决定将我的答案重新发布在这里,因为我认为这会增加一些价值。
如果更新依赖于在状态中找到的先前值,则应使用函数形式。如果在这种情况下不使用函数形式,那么代码有时会中断。
它为什么会断裂,何时断裂
React函数组件只是闭包,闭包中的状态值可能已经过时——这意味着闭包中的值与该组件处于React状态的值不匹配,这可能发生在以下情况案例:
1-异步操作(在本例中,单击“慢速添加”,然后多次单击“添加”按钮,稍后您将看到,当单击“慢速添加”按钮时,状态已重置为闭包内的状态)
const App = () => {
const [counter, setCounter] = useState(0);
return (
<>
<p>counter {counter} </p>
<button
onClick={() => {
setCounter(counter + 1);
}}
>
immediately add
</button>
<button
onClick={() => {
setTimeout(() => setCounter(counter + 1), 1000);
}}
>
Add
</button>
</>
);
};
2-在同一个闭包中多次调用update函数时
const App = () => {
const [counter, setCounter] = useState(0);
return (
<>
<p>counter {counter} </p>
<button
onClick={() => {
setCounter(counter + 1);
setCounter(counter + 1);
}}
>
Add twice
</button>
</>
);
}
我最近偶然发现需要这个。例如,假设你有一个组件,它用一些元素填充一个数组,并且能够根据用户的一些操作追加到该数组(就像在我的例子中,我一次加载10个项目,因为用户保持向下滚动屏幕。代码看起来像这样:
function Stream() {
const [feedItems, setFeedItems] = useState([]);
const { fetching, error, data, run } = useQuery(SOME_QUERY, vars);
useEffect(() => {
if (data) {
setFeedItems([...feedItems, ...data.items]);
}
}, [data]); // <---- this breaks the rules of hooks, missing feedItems
...
<button onClick={()=>run()}>get more</button>
...
显然,您不能只将feedItems添加到useEffect钩子中的依赖项列表中,因为您在其中调用setFeedItems,所以您将进入一个循环。
救援功能更新:
useEffect(() => {
if (data) {
setFeedItems(prevItems => [...prevItems, ...data.items]);
}
}, [data]); // <--- all good now
状态更新在React中是异步的。因此,当您下次更新它时,它可能会有旧值。例如,比较这两个代码示例的结果:
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => {
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1)}
}>+</button>
</>
);
}
和
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => {
setCount(count + 1);
setCount(count + 1)}
}>+</button>
</>
);
}
问题内容: 我认为这个问题已经存在,但是我找不到。 我不明白,为什么必须要有一个功能接口才能使用lambda。考虑以下示例: 这可以正常工作,但是如果您取消注释行,则不会。为什么?以我的理解,编译器应该能够区分这两种方法,因为它们具有不同的输入参数。为什么我需要一个功能接口并炸毁我的代码? 编辑:链接的重复项没有回答我的问题,因为我在询问不同的方法参数。但是在这里,我得到了一些非常有用的答案,这要
我只想问关于争论的事。方法名并不重要,但每个方法都采用不同参数的唯一顺序,因此Oracle可以实现这个特性,而不是让每个“lambda-interface”都有一个方法。
我正在考虑使用React Relay或Apollo客户端。我喜欢GraphQL作为一种查询语言的想法,它可以针对任何API或数据存储执行。 然而,我感到惊讶的是,在一个简单的变化之后,需要手动(并且必须)更新存储/缓存,比如在列表中添加一个待办事项。以下是更新程序/更新功能的文档: http://facebook.github.io/relay/docs/en/mutations.htmlhttp
问题内容: 在工作中,我们曾经以非常标准的OO方式对Python进行编程。最近,有几个人加入了实用的潮流行列。现在,他们的代码包含更多的lambda,映射和简化。我了解功能语言对并发性有好处,但对Python进行功能编程真的对并发有所帮助吗?我只是想了解如果我开始使用Python的更多功能,将会得到什么。 问题答案: 编辑 :由于没有提供更多的解释/示例,我被注释中的任务(部分地,似乎是由FP的狂
以我的拙见,关于“什么是单子”这个著名问题的答案,尤其是投票最多的答案,试图解释什么是单子,而没有明确解释为什么单子是真正必要的。它们能被解释为一个问题的解决方案吗?
问题内容: 该单页应用(SPA)已经到了我们。随之而来的还有很多新功能,例如路由,客户端页面生命周期,MVC模式,MVVM模式,MV *模式等等。还有一些Javascript模式,例如AMD模式,Singleton,Facade,.. 还开发了许多SPA框架和库。我们可以在互联网上找到它的一些内容。它们是AngularJs,Reactjs,BackboneJs,DurandalJs 等等,以及许多