繁体   English   中英

为什么我的 state 变量没有作为道具传递给子元素?

[英]Why is my state variable not getting passed as prop to a child element?

我正在尝试将主要 App 组件的 state 中的变量作为道具传递给名为ShoppingList的组件。 根据 React Dev Tools,由于某些奇怪的原因,即使它肯定在 App 组件的 state 中,它也没有通过。 但是,名为 Stocks 的几乎相同的组件接收其 state 变量作为道具,并且每个组件之间似乎没有区别。

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>
  );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM