刷新页面给出 'Page not found'。 (反应浏览器路由器)
Refreshing page gives 'Page not found'. (React BrowserRouter)
我用 React-Redux 构建了一个简单的 reddit 应用程序,当我转到像 /posts/mlxft5 这样的 post 页面并刷新页面时,它说找不到 post。我不知道如何解决它。这是我在 codesandbox 上的 code。
这是我的 app.js 代码
function App() {
return (
<Router >
<div className="App">
<div className="App-navbar">
<SubredditsList />
</div>
<Switch>
<Route exact path="/" component={StartMessage}/>
<Route exact path="/search" component={SearchPostsList}/>
<Route exact path="/posts" component={PostsList} />
<Route path="/posts/:postId" component={PostDetailRender}/>
<Route path="/search/:postId" component={SingleSearchPostRender}/>
<Redirect to="/" />
</Switch>
</div>
</Router>
)
}
export default App`
现在,当我们在 /posts
页面上进行 subreddit 时,您只从 API 请求 post。 /posts/mlxft
没有发起任何请求。我们需要添加一个额外的 thunk 操作,它可以从 id.
中获取和存储单个 post
当我们从 /posts
页面的列表中单击单个 post 时,我们不想获取已经存在于 Redux 中的 post。如果数据已经存在,我们将使用createAsyncThunk
函数的condition
setting来有条件地取消获取。
export const fetchSinglePost = createAsyncThunk(
"posts/fetchSingle",
async (postId) => {
const response = await fetch(
`https://api.reddit.com/api/info/?id=t3_${postId}`
);
const json = await response.json();
return json.data.children[0].data;
},
{
condition: (postId, { getState }) => {
const { posts } = getState();
if (posts.entities[postId]) {
return false;
}
}
}
);
您需要在 reducer 中添加额外的 case 来处理这个 thunk。注意:如果您使用 builder callback notation 而不是 reducer map 对象表示法,那么您可以合并两个“被拒绝”的案例。
[fetchSinglePost.pending]: (state, action) => {
state.status = "loading";
},
[fetchSinglePost.fulfilled]: (state, action) => {
state.status = "succeeded";
postsAdapter.upsertOne(state, action.payload);
},
[fetchSinglePost.rejected]: (state, action) => {
state.status = "failed";
state.error = action.error.message;
}
在您的 PostDetailRender
组件中,您需要 dispatch
fetchSinglePost
操作。可以在所有情况下分派它,因为 thunk 本身将取消获取。
useEffect(() => {
dispatch(fetchSinglePost(postId));
}, [dispatch, postId]);
您可以为每个 post 而不是整个切片一个 status
。我在 .
中解释了如何做到这一点
我还做了一些更改,这样您就不会多次获取相同的 subreddit 的 posts。
我用 React-Redux 构建了一个简单的 reddit 应用程序,当我转到像 /posts/mlxft5 这样的 post 页面并刷新页面时,它说找不到 post。我不知道如何解决它。这是我在 codesandbox 上的 code。 这是我的 app.js 代码
function App() {
return (
<Router >
<div className="App">
<div className="App-navbar">
<SubredditsList />
</div>
<Switch>
<Route exact path="/" component={StartMessage}/>
<Route exact path="/search" component={SearchPostsList}/>
<Route exact path="/posts" component={PostsList} />
<Route path="/posts/:postId" component={PostDetailRender}/>
<Route path="/search/:postId" component={SingleSearchPostRender}/>
<Redirect to="/" />
</Switch>
</div>
</Router>
)
}
export default App`
现在,当我们在 /posts
页面上进行 subreddit 时,您只从 API 请求 post。 /posts/mlxft
没有发起任何请求。我们需要添加一个额外的 thunk 操作,它可以从 id.
当我们从 /posts
页面的列表中单击单个 post 时,我们不想获取已经存在于 Redux 中的 post。如果数据已经存在,我们将使用createAsyncThunk
函数的condition
setting来有条件地取消获取。
export const fetchSinglePost = createAsyncThunk(
"posts/fetchSingle",
async (postId) => {
const response = await fetch(
`https://api.reddit.com/api/info/?id=t3_${postId}`
);
const json = await response.json();
return json.data.children[0].data;
},
{
condition: (postId, { getState }) => {
const { posts } = getState();
if (posts.entities[postId]) {
return false;
}
}
}
);
您需要在 reducer 中添加额外的 case 来处理这个 thunk。注意:如果您使用 builder callback notation 而不是 reducer map 对象表示法,那么您可以合并两个“被拒绝”的案例。
[fetchSinglePost.pending]: (state, action) => {
state.status = "loading";
},
[fetchSinglePost.fulfilled]: (state, action) => {
state.status = "succeeded";
postsAdapter.upsertOne(state, action.payload);
},
[fetchSinglePost.rejected]: (state, action) => {
state.status = "failed";
state.error = action.error.message;
}
在您的 PostDetailRender
组件中,您需要 dispatch
fetchSinglePost
操作。可以在所有情况下分派它,因为 thunk 本身将取消获取。
useEffect(() => {
dispatch(fetchSinglePost(postId));
}, [dispatch, postId]);
您可以为每个 post 而不是整个切片一个 status
。我在
我还做了一些更改,这样您就不会多次获取相同的 subreddit 的 posts。