这个代码首先不在服务器端呈现,需要刷新然后开始呈现的问题在哪里。单击“ RecipePage”页面的每个项目均假定重定向到该特定项目的详细信息页面。在此代码中,刷新RecipePage后的每次首次单击都会出现此错误:react_devtools_backend.js:6错误:最小化React错误#31;访问和详细信息页面的const mapStateToProps发送一个空的state.detail在客户端,而在服务器端则存在正确的数据。在详细信息页面上进行一次刷新后,客户端将开始工作,直到在RecipePage上进行下一次刷新为止。
server.js
const app = express();
app.use(cors());
app.options('*', cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use("/", index);
app.use(express.static("public"));
app.get("*", (req, res, next) => {
const store = createStore(reducers, {}, applyMiddleware(thunk));
const promises = matchRoutes(Routes, req.path).map(({ route,match }) => {
return route.loadedData ? route.loadedData(store,match.params._id) : null;
});
Promise.all(promises).then((a) => {
const home = renderToString(
<Provider store={store}>
<StaticRouter context={{}} location={req.path}>
<div>{renderRoutes(Routes)}</div>
</StaticRouter>
</Provider>
);
res.send(
`
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1"/>
<link href="https://fonts.googleapis.com/css?family=Righteous&display=swap"
rel="stylesheet" >
<link href="https://fonts.googleapis.com/css2?
family=Lato:wght@100;300;400;700;900&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?
family=Oswald:wght@200;300;400;500;600;700&display=swap" rel="stylesheet">
<link href="style.css" rel="stylesheet" type="text/css">
<link rel="shortcut icon" href="#">
<script src="https://kit.fontawesome.com/a076d05399.js"></script>
<title>server</title>
</head>
<body>
<div id="root">${home}</div>
<script>
window.INITIAL_STATE = ${serialize(store.getState())}
</script>
<script src="bundle.js" charset="utf-8"></script>
</body>
</html>
`
);
});
});
mongoose
.connect(
"mongodb+srv://laily:<password>.mongodb.net/page?retryWrites=true",
{ useNewUrlParser: true, useUnifiedTopology: true }
)
.then((result) => {
app.listen(4000, () => console.log("yesssssss"));
})
.catch((err) => {
console.log(err);
});
这是detail.js
class Detail extends Component {
componentDidMount() {
console.log(this.props.match.params,"paramsssss offffffdetasillll,this.props.location")
this.props.fetchRecipeDetail(this.props.match.params._id);
}
fetchProp(){
return <div>{this.props.detail}</div>
}
render() {
return (
<div>
{this.fetchProp()}
</div>
);
}
}
const mapStateToProps = (state) => {
return {
detail: state.detail,
};
};
const loadedData = (store,id) => {
return store.dispatch(fetchRecipeDetail(id));
};
export default {
loadedData,
component: connect(mapStateToProps, { fetchRecipeDetail })(Detail)
}
这是路线
export default [
{
...App,
routes: [
{
...Home,
path: '/',
exact: true,
},
{
...AddRecipe,
path: '/add-newrecipe',
},
{
...RecipePage,
path: '/all-recipes',
},
{
...Detail,
path: '/:_id',
},
{
...NotFound
}
]
} ]
这是动作部分
export const FFETCH_RECIPE_DETAIL = 'fetch_recipe_detail';
export const fetchRecipeDetail = (id) => async (dispatch) => {
const res= await axios.get(`http://localhost:4000/data/${id}`)
dispatch({
type: FFETCH_RECIPE_DETAIL,
detail:res.data,
});
};
这是减速器
import { FFETCH_RECIPE_DETAIL } from '../actions';
export default (state = {}, action) => {
switch (action.type) {
case FFETCH_RECIPE_DETAIL :
return action.detail.recipe._id;
default:
return state;
}
};