javascript - 为什么我的状态变量没有作为道具传递给子元素?
问题描述
我正在尝试将变量从主 App 组件的状态传递给名为ShoppingList
prop 的组件。出于某种奇怪的原因,即使根据 React Dev Tools 它肯定处于 App 组件的状态,它也没有通过。然而,一个几乎相同的名为 Stocks 的组件接收其状态变量作为道具,并且每个组件之间似乎没有区别。
const App = () => {
const [stockChange, setStockChange] = useState(false)
const [shoppingListChange, setShoppingListChange] = useState(false)
const [user, setUser] = useState('')
const [loggedIn, setLoggedIn] = useState(false)
const [stocks, setStocks] = useState('')
const [shoppingList, setShoppingList] = useState('')
useEffect(() => {
const loggedInUserJson = window.localStorage.getItem('loggedInUser')
if (loggedInUserJson) {
const userToken = JSON.parse(loggedInUserJson)
setUser(userToken)
setLoggedIn(true)
fetchUserDetails()
} else {
setUser(null)
setLoggedIn(false)
}
}, [loggedIn])
const putShoppingList = async () => {
console.log('put shopping')
return await axios.put(`http://localhost:3001/api/shoppinglists/${shoppingList._id}`, shoppingList,
{
headers: {
'Authorization': `Bearer ${user.token}`
}
})
}
useEffect(() => {
console.log('shopping list change')
putShoppingList()
.then(() => fetchUserDetails())
}, [shoppingListChange])
const fetchUserDetails = async () => {
const res = await axios.get('http://localhost:3001/api/users', {
headers: {
'Authorization': `Bearer ${user.token}`
}
})
setStocks(res.data.stocks)
setShoppingList(res.data.shoppinglists)
}
const putStocks = async () => {
console.log('put stocks')
return await axios.put(`http://localhost:3001/api/stocks/${stocks._id}`, stocks,
{
headers: {
'Authorization': `Bearer ${user.token}`
}
})
}
useEffect(() => {
console.log('stock change')
putStocks()
.then(() => fetchUserDetails())
}, [stockChange])
const logOut = () => {
window.localStorage.removeItem('loggedInUser')
setLoggedIn(false)
}
const getName = () => {
if (user) {
return user.name
} else {
return ''
}
}
return (
<StyledPage>
<Topbar id='topbar' loggedIn={loggedIn} name={getName()} logOut={logOut} />
<Sidebar />
<StyledMain>
<Switch>
<Route path='/login'>
<Login setUser={setUser} setLoggedIn={setLoggedIn} />
</Route>
<Route path='/register' component={Register} />
<Route path='/stock'>
<Stock stocks={stocks} setStocks={setStocks} setStockChange={setStockChange} stockChange={stockChange} />
</Route>
<Route path='/shoppinglist'>
<ShoppingList
shoppingList={shoppingList}
setShoppingList={setShoppingList}
shoppingListChange={shoppingListChange}
setShoppingListChange={setShoppingListChange}
/>
</Route>
</Switch>
</StyledMain>
</StyledPage>
);
}
我唯一的两个想法是 React Router 引起了问题,或者效果挂钩在首次渲染时会以某种方式干扰。
解决方案
您的代码有多个错误,尤其是依赖项和反应。你应该使用eslint-plugin-react-hooks
.
const App = () => {
const [stockChange, setStockChange] = useState(false)
const [shoppingListChange, setShoppingListChange] = useState(false)
const [user, setUser] = useState('')
const [loggedIn, setLoggedIn] = useState(false)
const [stocks, setStocks] = useState('')
const [shoppingList, setShoppingList] = useState('')
useEffect(() => {
const loggedInUserJson = window.localStorage.getItem('loggedInUser')
if (loggedInUserJson) {
const userToken = JSON.parse(loggedInUserJson)
setUser(userToken)
setLoggedIn(true)
fetchUserDetails()
} else {
setUser(null)
setLoggedIn(false)
}
}, [])
const putShoppingList = useCallback(async () => {
console.log('put shopping')
return await axios.put(`http://localhost:3001/api/shoppinglists/${shoppingList._id}`, shoppingList,
{
headers: {
'Authorization': `Bearer ${user.token}`
}
})
}, [shoppingList._id, user.token]);
const fetchUserDetails = useCallback(async () => {
const res = await axios.get('http://localhost:3001/api/users', {
headers: {
'Authorization': `Bearer ${user.token}`
}
})
setStocks(res.data.stocks)
setShoppingList(res.data.shoppinglists)
}, [user.token]);
useEffect(() => {
console.log('shopping list change')
putShoppingList()
.then(() => fetchUserDetails())
}, [])
const putStocks = useCallback(async () => {
console.log('put stocks')
return await axios.put(`http://localhost:3001/api/stocks/${stocks._id}`, stocks,
{
headers: {
'Authorization': `Bearer ${user.token}`
}
})
}, [stocks._id, user.token]);
useEffect(() => {
console.log('stock change')
putStocks()
.then(() => fetchUserDetails())
}, [])
const logOut = () => {
window.localStorage.removeItem('loggedInUser')
setLoggedIn(false)
}
const getName = () => {
if (user) {
return user.name
} else {
return ''
}
}
return (
<StyledPage>
<Topbar id='topbar' loggedIn={loggedIn} name={getName()} logOut={logOut}/>
<Sidebar />
<StyledMain>
<Switch>
<Route path='/login'>
<Login setUser={setUser} setLoggedIn={setLoggedIn}/>
</Route>
<Route path='/register' component={Register} />
<Route path='/stock'>
<Stock stocks={stocks} setStocks={setStocks} setStockChange={setStockChange} stockChange={stockChange}/>
</Route>
<Route path='/shoppinglist'>
<ShoppingList
shoppingList={shoppingList}
setShoppingList={setShoppingList}
shoppingListChange={shoppingListChange}
setShoppingListChange={setShoppingListChange}
/>
</Route>
</Switch>
</StyledMain>
</StyledPage>
);
}
推荐阅读
- javascript - 如何使用 Javascript 将多个音频文件附加到当前正在播放的音频中?
- android - 是否有任何方法可以清除我所有低于 21 的 android 应用程序任务(活动返回堆栈)?
- node.js - 有问题。邮政。评论模式 - Mongoose/Typescript
- mongodb - MongoDB - 如何在插入时引用父级中的子级/嵌套文档_id
- haskell - 如何确定一个 Enum 值是否是另一个 Enum 值的后继值?
- docker - 下载 Hyperledger Fabric docker 图像时遇到问题
- reactjs - 使用 Enzyme 更改 React 功能组件的 Props
- javascript - 如何将两个字段组合成第三个标签?
- azure - 在 Azure App Service for Containers 上启用 gzip 压缩
- xamarin - Xam.Plugin.Media 获取路径