【发布时间】:2020-07-07 13:43:31
【问题描述】:
我正在创建一个 MERN 堆栈在线商店网站,并且我正在从我的 Shoes.js 组件中的 useEffect 挂钩中获取我的产品。但我只是从 redux 获取初始状态,而不是更新状态。
正在获取数据,但我只能访问初始状态。所以传递给 ProductsArea 组件的值是 false 和 null 我如何获得更新的状态?
这是我的 Shoes.js 文件:
import React, { useEffect } from 'react';
import './Shoes.css';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { getProducts } from '../../../actions/productsActions';
import ProductsArea from './ProductsArea';
import Navbar from '../landing/Navbar';
import Search from './Search';
export const Shoes = (props) => {
useEffect(() => {
props.getProducts();
console.log(props.products);
console.log(props.loading);
}, []);
if(props.loading) {
return (
<h1>loading</h1>
)
}
else {
return (
<div>
<Navbar />
<div className="shoes">
<Search />
<h1 className="productsTitle">Our Selection</h1>
<ProductsArea loading={props.loading} products={props.products} />
{/* {
props.products.map(product => (
<ProductCard key={product._id} product={product} />
))
} */}
</div>
</div>
)
}
}
const mapStateToProps = state => ({
products: state.products.products,
loading: state.products.loading
})
export default connect(mapStateToProps, { getProducts })(Shoes);
这是我的 productsActions 文件
import {GET_PRODUCTS, SET_LOADING, SET_ERROR} from './types';
export const getProducts = () => async (dispatch) => {
try{
setLoading();
const res = await fetch('http://localhost:5000/products');
const data = await res.json();
console.log(data);
dispatch({
type: GET_PRODUCTS,
payload: data
});
}
catch(err) {
dispatch({
type: SET_ERROR,
payload: err
})
}
}
export const setLoading = () => {
console.log('Loading true');
return {
type: SET_LOADING
}
}
这是 getProductsReducer 文件:
import {GET_PRODUCTS, SET_LOADING, SET_ERROR} from '../actions/types';
const initialState = {
products: [],
loading: false,
error: null
}
export default (state = initialState, action) => {
switch (action.type) {
case GET_PRODUCTS:
console.log(action.payload);
return {
...state,
products: action.payload,
loading: false
}
case SET_LOADING:
return {
...state,
loading: true
};
case SET_ERROR:
console.log(action.payload);
return {
...state,
error: action.payload
};
default: return state;
}
}
这是我用于 redux 的 index.js 文件:
import {combineReducers} from 'redux';
import getProductReducer from './getProductReducer';
export default combineReducers({
products: getProductReducer
});
还有 Store.js 文件:
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const initialState = {};
const middleware = [thunk];
const store = createStore(rootReducer, initialState, composeWithDevTools(applyMiddleware(...middleware)));
export default store;
所以我检查了 redux 扩展,状态显示在我的 Home.js 页面上,但没有显示在 Shoes.js 文件中
这是 Home.js 文件:
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { getProducts, setLoading } from '../../../actions/productsActions';
import { connect } from 'react-redux';
import {Link} from 'react-router-dom';
import './Home.css';
import Navbar from './Navbar';
export const Home = (props) => {
useEffect(() => {
props.setLoading();
props.getProducts();
//eslint-disable-next-line
console.log(props.products);
console.log(props.loading);
}, []);
if(props.loading) {
return <div>loading</div>
}
else {
return (
<div>
<Navbar />
<div className="home">
<div className="group-1">
<div className="branding">
<div className="brandName">
The
<br/>
Sole
<br/>
Store
</div>
<div>
<p>The finest designs and fits.</p>
</div>
</div>
<div className="viewProducts">
<div>
<p>
Check out our latest and greatest models
</p>
<Link className="productsBtn" to="/shoes">GO <i className="fas fa-arrow-right"/></Link>
</div>
</div>
</div>
<div className="group-2">
<div className="products">
<div className="product"></div>
<div className="product"></div>
<div className="product"></div>
<div className="product"></div>
</div>
<div className="something"></div>
</div>
</div>
</div>
)
}
}
Home.propTypes = {
products: PropTypes.object.isRequired,
loading: PropTypes.bool.isRequired
}
const mapStateToProps = state => ({
products: state.products.products,
loading: state.products.loading
});
export default connect(mapStateToProps, {getProducts, setLoading})(Home);
尽管如此,我仍然只能从 Home.js 获取控制台中的初始状态,而不是更新状态。
我已经按照@Kalhan.Toress 的建议进行了更改,这是更新后的 Shoes.js 文件
import React, { useEffect } from 'react';
import './Shoes.css';
// import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { getProducts } from '../../../actions/productsActions';
import ProductsArea from './ProductsArea';
import Navbar from '../landing/Navbar';
import Search from './Search';
export const Shoes = (props) => {
useEffect(() => {
props.fetchData();
console.log(JSON.parse(props.products.products));
}, []);
if(props.loading) {
return (
<h1>loading</h1>
)
}
else {
return (
<div>
<Navbar />
<div className="shoes">
<Search />
<h1 className="productsTitle">Our Selection</h1>
<ProductsArea loading={props.loading} products={JSON.parse(props.products.products)} />
{/* {
props.products.map(product => (
<ProductCard key={product._id} product={product} />
))
} */}
</div>
</div>
)
}
}
const mapDispatchToProps = dispatch => {
return {
fetchData: () => dispatch(getProducts())
};
};
const mapStateToProps = state => ({
products: state.products.products,
loading: state.products.loading
})
export default connect(mapStateToProps, mapDispatchToProps)(Shoes);
我可以从主页单击指向 Shoes 页面的链接,一切正常,但是一旦我重新加载 Shoes.js 页面或直接转到它,我得到的错误是: 错误:引发了跨域错误。 React 无法访问开发中的实际错误对象。
这是我启用了 CORS 的服务器端的 App.js 文件:
const express = require('express');
const app = express();
const bodyParser = require('body-parser')
const productRoute = require('./products/productRoute');
const orderRoute = require('./orders/orderRoute');
const userRoute = require('./users/userRoute');
const adminRoute = require('./admins/adminRoute');
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin','*');
res.header('Access-Control-Allow-Headers','Origin, X-Requested-With, Content-Type, Authorization, Accept');
if(res.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, PATCH, DELETE');
}
next();
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use('/products', productRoute);
app.use('/orders', orderRoute);
app.use('/users', userRoute);
app.use('/admin', adminRoute);
app.use((req, res, next) => {
const error = new Error();
error.status = 404;
next(error);
});
app.use((error, req, res, next) => {
res.status(error.status || 500 ).json({
error: error
})
});
module.exports = app;
非常感谢任何帮助! 谢谢!
【问题讨论】:
-
console.log(action.payload);in reducer 有什么好处 -
我得到了 products 数组,这就是我要找的
-
如何在 redux 开发工具中探索状态?你的状态符合你的预期吗?
-
我检查并使用另一个文件更新了我的帖子,该文件正在更新 redux 中的状态。但是 Shoes.js 没有在 redux 开发者工具中显示更新状态
标签: reactjs react-redux react-hooks