setState()在第一次单击时不起作用!状态值仅在第二,第三.... clicks上更新。我使用适当的上下文和导入来处理状态!
我将快速总结一下我正在执行的顶部导航栏有两个按钮,即主页和购物车。
侧面导航栏具有三个英雄按钮,单击可渲染相应的英雄商店,其中包含带有+和-按钮的T恤, socks 和鞋子,以增加或减少数量。
每次单击时,显示数量的跨度值会正确增加,但购物车按钮会显示数量(不包括首次点击)。就像当我将T恤的值增加到1时,购物车按钮不显示任何值,当我将T恤的值增加到2时,购物车按钮显示1
cartButton使用状态CartValue
T恤, socks ,鞋子使用状态HeroGoods
(live demo) click here 看我在说什么
我不确定即时通讯是否允许在此处发布所有组件和外部链接(如github)。但是无论如何,如果你们不能从下面的代码here's link to the github repo看我出了错
import React , {useState,useEffect}from 'react';
import Navmenu from './Navmenu'
import SideNav from './SideNav'
import ActionDiv from './ActionDiv'
import ActionHeroStore from './ActionHeroStore'
import ActionCart from './ActionCart'
import '../css/main.css'
export const HeroContext=React.createContext()
const emptyGood={
tshirts:0,
shoes:0,
socks:0,
}
const emptyCart={
batman:{
tshirts:0,
shoes:0,
socks:0,
},
superman:{
tshirts:0,
shoes:0,
socks:0,
},
greenlantern:{
tshirts:0,
shoes:0,
socks:0,
},
}
function empty()
{
return null
}
function App() {
const [hero,setHero]=useState(null)
const [cartValue,setCartValue]=useState(emptyCart)
const [batmanGoods,setBatmanGoods]=useState(emptyGood)
const [supermanGoods,setSupermanGoods]=useState(emptyGood)
const [greenLanternGoods,setGreenLanternGoods]=useState(emptyGood)
const [showCart,setShowCart]=useState(false)
function handleUpdateGoods(hero,obj){
hero=='batman'?
setBatmanGoods(prevState=>{
return {...prevState,...obj}
}):
hero=='superman'?
setSupermanGoods(prevState=>{
return {...prevState,...obj}
}):
hero=='greenlantern'?
setGreenLanternGoods(prevState=>{
return {...prevState,...obj}
}):
empty()
}
function handleHeroSelect(name){
setHero(prevState=>prevState=name)
}
function handleCartValue(value)
{
setCartValue(value)
}
function handleShowCart(status)
{
setShowCart(status)
}
function giveHeroGoods(hero,element)
{
return (
hero=='batman'?batmanGoods[element]:
hero=='superman'?supermanGoods[element]:
hero=='greenlantern'?greenLanternGoods[element]:empty()
)
}
function handleUpdateCart(name){
name=='batman'?
setCartValue(prevState=>{
return {...prevState,batman:{...batmanGoods}}
}):
name=='superman'?
setCartValue(prevState=>{
return {...prevState,superman:{...supermanGoods}}
}):
name=='greenlantern'?
setCartValue(prevState=>{
return {...prevState,greenlantern:{...greenLanternGoods}}
}):
empty()
}
const heroContextValue={
handleHeroSelect,
handleCartValue,
handleUpdateGoods,
giveHeroGoods,
handleUpdateCart,
handleShowCart
}
return (
<>
<HeroContext.Provider value={heroContextValue}>
<Navmenu cartValue={cartValue}/>
<div className="mainContent">
<SideNav cartValue={cartValue}/>
{hero==null && !showCart &&<ActionDiv/>}
{hero!==null && !showCart && <ActionHeroStore hero={hero}/>}
{showCart && <ActionCart cartValue={cartValue}/>}
</div>
</HeroContext.Provider>
</>
)
}
export default App;
import React ,{useContext} from 'react'
import {HeroContext} from './App'
export default function Navmenu(props) {
const {cartValue}=props
const {handleHeroSelect,handleShowCart}=useContext(HeroContext)
function giveGoodsSum(obj)
{
return obj.tshirts+obj.socks+obj.shoes
}
function giveCartValue(cartValue){
let sum=0
for(let key in cartValue)
{
sum=sum+giveGoodsSum(cartValue[key])
}
return(
sum!==0?sum:null
)
}
return (
<div
className="navMenu"
>
<button
className="homeButton"
onClick={()=>{
handleHeroSelect(null)
handleShowCart(false)
}}
>
Home
</button>
<button
className="cartButton"
onClick={()=>{
handleHeroSelect(null)
handleShowCart(true)
}}
>
cart
<span
>
{giveCartValue(cartValue)}
</span>
</button>
</div>
)
}
import React ,{useContext} from 'react'
import {HeroContext} from './App'
export default function SideNav() {
const {handleHeroSelect}=useContext(HeroContext)
return (
<div className="sideNav">
<div
className="batman"
onClick={()=>handleHeroSelect('batman')}
/>
<div
className="superman"
onClick={()=>handleHeroSelect('superman')}
/>
<div
className="greenlantern"
onClick={()=>handleHeroSelect('greenlantern')}
/>
</div>
)
}
import React from 'react'
import ActionHeroStoreGoods from './ActionHeroStoreGoods'
export default function ActionHeroStore(props) {
const {hero}=props
return (
<div className={`actionHeroStore ${hero}div`}>
<h3>{hero}</h3>
<div className="actionHeroStore_goods">
<ActionHeroStoreGoods hero={hero}/>
</div>
</div>
)
}
import React, { Fragment,useContext } from 'react'
import {HeroContext} from './App'
export default function ActionHeroStoreGoods({hero}) {
const {giveHeroGoods,
handleUpdateGoods,
handleUpdateCart
}=useContext(HeroContext)
const goods=['tshirts','shoes','socks'];
const goodsElement=goods.map((element,index) => {
return <Fragment key={index}>
<div className="soloGood">
<span>{element}</span>
<button
onClick={
()=>decrement(hero,element)
}>-</button >
<span>{giveHeroGoods(hero,element)}</span>
<button onClick={
()=>{
increment(hero,element)
handleUpdateCart(hero)
}
}>+</button>
</div>
</Fragment>
})
function increment(hero,element){
let updateObj={};
updateObj[element]=giveHeroGoods(hero,element)+1
handleUpdateGoods(hero,updateObj)
}
function decrement(hero,element){
if(giveHeroGoods(hero,element)>0)
{
let updateObj={};
updateObj[element]=giveHeroGoods(hero,element)-1
handleUpdateGoods(hero,updateObj)
}
}
return (
<>
{goodsElement}
</>
)
}
最佳答案
问题不在setState中。代码中的问题。在* Goods状态更改之前,将调用handleUpdateCart()函数。因此,它适用于旧数据。如果要在“App.js”文件中添加以下片段:
...
...
function giveHeroGoods(hero,element)
{
return (
hero=='batman'?batmanGoods[element]:
hero=='superman'?supermanGoods[element]:
hero=='greenlantern'?greenLanternGoods[element]:empty()
)
}
// FROM HERE
React.useEffect(() => {
handleUpdateCart('batman');
}, [
batmanGoods
]);
React.useEffect(() => {
handleUpdateCart('superman');
}, [
supermanGoods
]);
React.useEffect(() => {
handleUpdateCart('greenlantern');
}, [
greenLanternGoods
]);
// TILL HERE
function handleUpdateCart(name){
...
...
关于javascript - react setState()不适用于第一次单击,但在第二次,第三次…单击时工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62585711/