无法在按钮单击 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();没有在按钮单击时重定向页面

React.js身份验证在每次刷新时重定向到登录名

结束对话范围的 bean,然后在单击命令按钮时重定向

当用户在 JSF 中注销后单击后退按钮时重定向到登录页面 [重复]

Flutter:当应用程序处于后台但未在 iOS 中终止时,无法在通知单击时重定向到特定屏幕

如何在mvc中单击按钮时重定向到另一个页面和特定的div