在 React 中,"history.push('/')"在某些组件中不起作用



我正在尝试从qnannews .js重定向功能。

onSubmit = (formProps) => {
this.props.createPost(formProps, () => {
this.props.history.push('/qna');
});
};

我想让它当我发送post请求然后重定向到'/qna'。奇怪的是,重定向工作在Login.js, Join.js页面。

history.js

import { createBrowserHistory } from 'history';
export default createBrowserHistory();

src - index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from 'react-router-dom';
import './index.css';
import App from './App';
import history from './history';
// Redux
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import reducers from './reducers';
import reduxThunk from 'redux-thunk';
const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducers,
{
auth: { authenticated: localStorage.getItem('token') },
},
composeEnhancer(applyMiddleware(reduxThunk))
);
ReactDOM.render(
<Provider store={store}>
<Router history={history}>
<App />
</Router>
</Provider>,
document.getElementById('root')
);

QnANew.js

import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import { compose } from 'redux';
import { connect } from 'react-redux';
import * as actions from '../../actions';
//import { createPost } from '../../actions'

class QnANew extends Component {
renderInput({ input, label, meta }) {
return (
<div className="qnaTitle">
<label>{label}</label>
<input {...input} />
<div>{meta.error}</div>
</div>
);
}
renderEditor({ input, label }) {
return (
<div className="qnaContent">
<label>{label}</label>
<CKEditor
data={input.value}
editor={ClassicEditor}
onChange={(event, editor) => {
return input.onChange(editor.getData());
}}
/>
</div>
);
}
onSubmit = (formProps) => {
this.props.createPost(formProps, () => {
this.props.history.push('/qna');
});
};
render() {
const { handleSubmit } = this.props;
return (
<div className="QnaNew">
<h2>Using CKEditor 5 build in React</h2>
<h2>Using CKEditor 5 build in React</h2>
<h2>Using CKEditor 5 build in React</h2>
<h2>Using CKEditor 5 build in React</h2>
<h2>Using CKEditor 5 build in React</h2>
<form onSubmit={handleSubmit(this.onSubmit)} className="ui form">
<fieldset>
<Field name="title" type="text" component={this.renderInput} label="Enter Title" autoComplete="none" />
</fieldset>
<fieldset>
<Field name="content" type="text" component={this.renderEditor} label="Enter Description" autoComplete="none" />
</fieldset>
<button type="submit">Submit</button>
</form>
</div>
);
}
}


const validate = (formValues) => {
const errors = {};
if (!formValues.title) {
errors.title = 'You must enter a title';
}
return errors;
}

const formWrapped = reduxForm({ form: 'QnANew', validate })(QnANew);
export default compose(connect(null, actions))(formWrapped);

actions - index.js

import axios from 'axios';
import history from '../history';
import qna from '../apis/qna';
import { AUTH_USER, AUTH_ERROR, CREATE_QNA, FETCH_QNA, FETCH_QNAS, EDIT_QNA, DELETE_QNA } from './types';
export const join = (formProps, callback) => async dispatch => {
try {
const response = await axios.post('http://localhost:3001/join', formProps);
dispatch({ type: AUTH_USER, payload: response.data.token });
localStorage.setItem('token', response.data.token);
callback();
} catch (e) {
dispatch({ type: AUTH_ERROR, payload: 'Email in use'});
}
}

export const login = (formProps) => async (dispatch) => {
try {
const response = await axios.post('http://localhost:3001/login', formProps);

dispatch({ type: AUTH_USER, payload: response.data.token });
localStorage.setItem('token', response.data.token);
history.push('/'); 
} catch (e) {
dispatch({ type: AUTH_ERROR, payload: 'Invalid login credentials' });
}
};

export const logout = () => {
localStorage.removeItem('token');
return {
type: AUTH_USER,
payload: ''
};
}

export const createPost = (formProps) => async (dispatch) => {
const response = await qna.post('/qnanew', { ...formProps });
dispatch({ type: CREATE_QNA, payload: response.data });
history.push('/qna');
};
export const fetchPost = (id) => async dispatch => {
const response = await qna.get(`/qna/${id}`);
dispatch({ type: FETCH_QNA, payload: response.data });
};

// Post List
export const fetchPosts = () => async dispatch => {
const response = await qna.get('/qna');
dispatch({ type: FETCH_QNAS, payload: response.data });
};
export const editPost = (id, formValues) => async dispatch => {
const response = await qna.put(`/qna/${id}`, formValues);
dispatch({ type: EDIT_QNA, payload: response.data });
};
export const deletePost = (id) => async dispatch => {
await qna.delete(`/qna/${id}`);
dispatch({ type: DELETE_QNA, payload: id });
}

Login.js

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { compose } from 'redux';
import { connect } from 'react-redux';
import * as actions from '../actions';
import './Login.scss';
class Login extends Component {
onSubmit = (formProps) => {
this.props.login(formProps, () => {
this.props.history.push('/');
});
};
render() {
const { handleSubmit } = this.props;
return (
<div className="Join">
<h1>Login</h1>
<p>Login page</p>
<form onSubmit={handleSubmit(this.onSubmit)} className="JoinForm">
<fieldset>
<label>Email</label>
<Field name="email" type="text" component="input" autoComplete="none" />
</fieldset>
<fieldset>
<label>Password</label>
<Field name="password" type="password" component="input" autoComplete="none" />
</fieldset>
<div>{this.props.errorMessage}</div>
<button type="submit">Login</button>
</form>
</div>
);
}
}
function mapStateToProps(state) {
return { errorMessage: state.auth.errorMessage };
}
export default compose(connect(mapStateToProps, actions), reduxForm({ form: 'login' }))(Login);

可以这样使用:

this.props.history.push('/');
this.props.history.go('/');

或:

window.location.href = "/";

最新更新