我是新手。现在我面临一个问题。我的应用程序运行良好(一个简单的电子商务(。当我输入送货地址时,它运行良好。但问题是,当我从该帐户注销并在发货页面中再次登录时,它会向我显示这样的错误,
类型错误:无法读取null的属性"address">
我正在使用redux。因此,当我从浏览器Localstorage中删除现有地址时,它运行良好。显示时出错
ShippingScreen.js
import React,{useState,useEffect} from 'react'
import { Form,Button } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import FormContainer from '../components/FormContainer'
import { saveShippingAddress } from '../actions/cartActions'
import CheckoutSteps from '../components/CheckoutSteps'
function ShippingScreen({history}) {
const cart = useSelector(state => state.cart)
const { shippingAddress } = cart
const dispatch = useDispatch()
const [address, setAddress] = useState(shippingAddress.address)
const [phone, setPhone] = useState(shippingAddress.phone)
const [city, setCity] = useState(shippingAddress.city)
const [postalCode, setPostalCode] = useState(shippingAddress.postalCode)
const [country, setCountry] = useState(shippingAddress.country)
const submitHandler = (e) =>{
e.preventDefault()
dispatch(saveShippingAddress({ address,phone,city,postalCode,country }))
history.push('/payment')
}
return (
<FormContainer>
<CheckoutSteps step1 step2 />
<h1>Shipping Information</h1>
<Form onSubmit={submitHandler}>
<Form.Group controlId='address'>
<Form.Label>Address</Form.Label>
<Form.Control
required
type='text'
placeholder='Enter Address'
value={address ? address : ''}
onChange={(e)=> setAddress(e.target.value)}>
</Form.Control>
</Form.Group>
<Form.Group controlId='phone'>
<Form.Label>Phone Number</Form.Label>
<Form.Control
required
type='number'
placeholder='Enter Phone Number'
value={phone ? phone : ''}
onChange={(e)=> setPhone(e.target.value)}>
</Form.Control>
</Form.Group>
<Form.Group controlId='city'>
<Form.Label>City</Form.Label>
<Form.Control
required
type='text'
placeholder='Enter City'
value={city ? city : ''}
onChange={(e)=> setCity(e.target.value)}>
</Form.Control>
</Form.Group>
<Form.Group controlId='postalCode'>
<Form.Label>Post Code</Form.Label>
<Form.Control
required
type='number'
placeholder='Enter Post Code'
value={postalCode ? postalCode : ''}
onChange={(e)=> setPostalCode(e.target.value)}>
</Form.Control>
</Form.Group>
<Form.Group controlId='country'>
<Form.Label>Country</Form.Label>
<Form.Control
required
type='text'
placeholder='Enter Country'
value={country ? country : ''}
onChange={(e)=> setCountry(e.target.value)}>
</Form.Control>
</Form.Group>
<Button type='submit' variant='primary'>
Coninue
</Button>
</Form>
</FormContainer>
)
}
export default ShippingScreen
cartReducer.js
import { CART_ADD_ITEM,
CART_REMOVE_ITEM,
CART_SAVE_SHIPPING_ADDRESS,
CART_SAVE_PAYMENT_METHOD
} from '../constants/cartConstants'
export const cartReducer = (state={ cartItems:[], shippingAddress: {} },action) =>{
switch (action.type){
case CART_ADD_ITEM:
const item=action.payload
const existItem=state.cartItems.find(x=>x.product===item.product)
if(existItem){
return{
...state,
cartItems: state.cartItems.map(x=>
x.product === existItem.product ? item : x
)
}
}else{
return{
...state,
cartItems:[...state.cartItems, item]
}
}
case CART_REMOVE_ITEM:
return{
...state,
cartItems:state.cartItems.filter(x => x.product !== action.payload)
}
case CART_SAVE_SHIPPING_ADDRESS:
return{
...state,
shippingAddress: action.payload
}
case CART_SAVE_PAYMENT_METHOD:
return{
...state,
paymentMethod: action.payload
}
default:
return state
}
}
cartAction.js
import axios from 'axios'
import { CART_ADD_ITEM,
CART_REMOVE_ITEM,
CART_SAVE_SHIPPING_ADDRESS,
CART_SAVE_PAYMENT_METHOD,
} from '../constants/cartConstants'
export const addToCart = (id, qty) => async (dispatch, getState)=>{
const {data} =await axios.get(`http://127.0.0.1:8000/api/products/${id}`)
dispatch({
type:CART_ADD_ITEM,
payload:{
product: data._id,
name: data.name,
image: data.image,
price: data.price,
countInStock: data.countInStock,
qty
}
})
localStorage.setItem('cartItem' , JSON.stringify(getState().cart.cartItems))
}
export const removeFromCart = (id)=>(dispatch, getState) => {
dispatch({
type:CART_REMOVE_ITEM,
payload:id,
})
localStorage.setItem('cartItem' , JSON.stringify(getState().cart.cartItems))
}
export const saveShippingAddress = (data)=>(dispatch) => {
dispatch({
type:CART_SAVE_SHIPPING_ADDRESS,
payload:data,
})
localStorage.setItem('shippingAddress' , JSON.stringify(data))
}
export const savePaymentMethod = (data)=>(dispatch) => {
dispatch({
type:CART_SAVE_PAYMENT_METHOD,
payload:data,
})
localStorage.setItem('paymentMethod' , JSON.stringify(data))
}
store.js
import { createStore, combineReducers, applyMiddleware } from 'redux'
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';
import { productListReducers,productDetailsReducers } from './reducers/productReducers';
import { cartReducer } from './reducers/cartReducers'
import { userLoginReducer, userRegisterReducer, userDetailsReducer, userUpdateProfileReducer } from './reducers/userReducers'
import { orderCreateReducer } from './reducers/orderReducers'
const reducer = combineReducers({
productList: productListReducers,
productDetails: productDetailsReducers,
cart: cartReducer,
userLogin: userLoginReducer,
userRegister: userRegisterReducer,
userDetails:userDetailsReducer,
userUpdateProfile:userUpdateProfileReducer,
orderCreate:orderCreateReducer,
})
const cartItemsFromStorage = localStorage.getItem('cartItems') ?
JSON.parse(localStorage.getItem('cartItems')) : []
const userInfoFromStorage = localStorage.getItem('userInfo') ?
JSON.parse(localStorage.getItem('userInfo')) : null
const shippingAddressFromStorage = localStorage.getItem('shippingAddress') ?
JSON.parse(localStorage.getItem('sgippingAddress')) : {}
const intitialState = {
cart:{
cartItems: cartItemsFromStorage,
shippingAddress: shippingAddressFromStorage,
},
userLogin:{userInfo: userInfoFromStorage},
}
const middleware = [thunk]
const store= createStore(reducer,intitialState,
composeWithDevTools(applyMiddleware(...middleware)))
export default store
尝试从本地存储获取shippingAddress
时,store.js
文件出现拼写错误。您编写了sgippingAddress
,但应该是shippingAddress
和h
。
您的store.js;(
const shippingAddressFromStorage = localStorage.getItem('shippingAddress') ?
JSON.parse(localStorage.getItem('->sg<-ippingAddress')) : {}
您可以考虑使用redux-persistent,这是一个很好的库,可以将您的redux-state持久化到localStorage、indexDB等。