无法在按钮单击 React.js 时重定向(使用上下文提供程序)
Posted
技术标签:
【中文标题】无法在按钮单击 React.js 时重定向(使用上下文提供程序)【英文标题】:Unable to redirect on button click React.js (using context provider) 【发布时间】:2021-06-09 19:56:49 【问题描述】:我是 React 新手,在从我的 API 获得响应后,我一直在尝试重定向到不同的组件。
我尝试过使用历史记录、位置和重定向,但重定向从未发生。
另外,当我使用以上所有方法时,我会得到undefined
。
我不确定这是否是因为我的 App 是在 Router 之外定义的,如果这是我仍然无法解决问题的原因。
这是我的代码:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import AppProvider from './Context'
import BrowserRouter as Router from 'react-router-dom'
ReactDOM.render(
<React.StrictMode>
<AppProvider>
<App />
</AppProvider>
</React.StrictMode>,
document.getElementById('root')
);
App.js
import React from 'react';
import './App.css';
import Home, JoinRoom, CreateRoom, Room from './pages';
import BrowserRouter as Router, Switch, Route from 'react-router-dom';
function App()
return (
<div className="App">
<Router>
<Switch>
<Route path="/" exact=true>
<Home />
</Route>
<Route path="/join">
<JoinRoom />
</Route>
<Route path="/create">
<CreateRoom />
</Route>
<Route path="/room/:roomCode">
<Room />
</Route>
</Switch>
</Router>
</div>
);
export default App;
Context.js
在 handleRoomButtonPressed
中,我正在从 API 获取数据并尝试重定向。
import React, useState, useContext from 'react';
import axios from 'axios';
import Redirect, useHistory from "react-router-dom";
const AppContext = React.createContext()
const AppProvider = ( children ) =>
// const history = useHistory();
const [guestCanPause, setGuestCanPause] = useState(true);
const [votesToSkip, setVotesToSkip] = useState(2);
const [isHost, setIsHost] = useState(false);
const handleVotesChange = (e) =>
e.preventDefault();
setVotesToSkip(e.target.value);
const handleGuestCanPauseChange = (e) =>
e.preventDefault();
setGuestCanPause(e.target.value)
const handleRoomButtonPressed = async (props) =>
const roomData = guest_can_pause: guestCanPause, votes_to_skip: votesToSkip ;
const response = await axios.post('/api/create-room/', roomData);
console.log(response.data)
const redirectUrl = "/room/" + response.data.code;
console.log(props)
return <Redirect to=redirectUrl />
const getRoomDetails = async (roomCode) =>
axios
.get("/api/get-room?code=" + roomCode)
.then((res) =>
console.log(res.data)
setVotesToSkip(res.data.votes_to_skip);
setGuestCanPause(res.data.guest_can_pause);
setIsHost(res.data.is_host);
)
.catch((err) => console.log(err));
return <AppContext.Provider value= guestCanPause,
votesToSkip,
isHost,
handleGuestCanPauseChange,
handleVotesChange,
handleRoomButtonPressed,
getRoomDetails, >
children
</AppContext.Provider>
export const useGlobalContext = () =>
return useContext(AppContext)
export AppContext, AppProvider
onClick
在 CreateRoom.js 中被调用
import React, useState, from 'react';
import useGlobalContext from '../Context'
import Link from 'react-router-dom';
import Button, Grid, Typography, TextField, FormHelperText, FormControl, Radio, RadioGroup, FormControlLabel from '@material-ui/core'
function CreateRoom()
const defaultVotes = 2;
const handleGuestCanPauseChange, handleVotesChange, handleRoomButtonPressed = useGlobalContext();
return (
<Grid container spacing=1>
<Grid item xs=12 align="center">
<Typography component="h4" variant="h4">
Create A Room
</Typography>
</Grid>
<Grid item xs=12 align="center">
<FormControl component="fieldset">
<FormHelperText>
<div align="center">Guest Control of Playback state</div>
</FormHelperText>
<RadioGroup row defaultValue="true" onChange=handleGuestCanPauseChange>
<FormControlLabel value="true"
control=<Radio color="primary" />
label="Play/Pause" labelPlacemment="bottom" />
<FormControlLabel value="false"
control=<Radio color="secondary" />
label="No Control" labelPlacemment="bottom" />
</RadioGroup>
</FormControl>
</Grid>
<Grid item xs=12 align="center">
<FormControl>
<TextField required=true
type="number" onChange=handleVotesChange
defaultValue=defaultVotes
inputProps= min: 1,
style: textAlign: "center" ,
/>
<FormHelperText>
<div align="center">Votes Required To Skip Song</div>
</FormHelperText>
</FormControl>
</Grid>
<Grid item xs=12 align="center">
<Button
color="primary"
variant="contained"
onClick=handleRoomButtonPressed
>
Create A Room
</Button>
</Grid>
<Grid item xs=12 align="center">
<Button color="secondary" variant="contained" to="/" component=Link>
Back
</Button>
</Grid>
</Grid>
)
export default CreateRoom
【问题讨论】:
【参考方案1】:如果我正确理解了一个主题,您的 AppProvider 位于组件树中的路由器上方。因此,react 路由器无法将其依赖项注入您的 AppProvider。如果你想访问 react-router API,例如 useHistory hook 或其他,你应该从 Router 子节点之一调用它,然后它会起作用。
【讨论】:
感谢您的回复,是的,我的AppProvider
位于路由器上方。但是,我不完全理解如何在其中一个路由器子节点中使用UseHistory
。您能否提供一个参考我的代码的示例?另外,有什么方法可以在我的 Provider 中进行重定向?以上是关于无法在按钮单击 React.js 时重定向(使用上下文提供程序)的主要内容,如果未能解决你的问题,请参考以下文章
window.location.replace();没有在按钮单击时重定向页面
当用户在 JSF 中注销后单击后退按钮时重定向到登录页面 [重复]