提交时重定向 React 表单组件。反应路由器 v5.1
Redirect React form component on submit. React Router v5.1
目标 - 我有一个用于更新产品详细信息的表格。
我想在提交表单时重定向到主页。
问题 是我将表单数据从我的 Form
组件发送到主 App
组件以更新产品列表。产品处于我的 App
状态,并作为道具传递给我的 Form
,这会导致 Form
组件重新渲染。
Form
有一个在构造函数中设置为 false 的状态标志:toHome: false
。我的计划是利用 react-router 的 Redirect
在标志设置为 true 时触发。
在 EditForm
handleSubmit 方法中有一个 setState({ toHome: true })
。但是在 handleSubmit 中还有方法(作为道具从 App
传递)来更新处于 App
状态的产品。
TLDR -> Form
handleSubmit 更新产品 -> Form
重新呈现 -> 重定向标志 (toHome
) 设置为 false在构造函数中 - >重定向永远不会发生。
即使我想添加一个简短的成功消息,我也有同样的问题。我已经坚持这个太久了。
EditForm.js
import React, { Component } from 'react'
import { Link, Redirect } from 'react-router-dom'
import PropTypes from 'prop-types'
class EditForm extends Component {
constructor(props) {
super(props)
this.state = {
product: {
id: '',
name: '',
description: '',
price: {
base: '',
amount: ''
},
relatedProducts: []
},
productIndex: '',
toHome: false
}
}
componentDidMount() {
const { productId, allProducts } = this.props
const thisProduct = this.findProduct(productId, allProducts)
const thisIndex = this.findIndex(productId, allProducts)
this.setState({ product: { ...thisProduct }, productIndex: thisIndex })
}
.........
handleSubmit(e) {
e.preventDefault()
const newAllProducts = this.mergeProducts()
// this is the method that's firing the re-render
this.props.updateProducts(newAllProducts)
// and here is the ill-fated setState
this.setState({ toHome: true })
}
render() {
const { id, name, description, price, toHome } = this.state.product
console.log(this.state.toHome)
if (toHome) {
return <Redirect to="/" />
}
return (
<div className="edit-form">
....form...
</div>
</div>
)
}
}
EditForm.propTypes = {
productId: PropTypes.number.isRequired,
allProducts: PropTypes.array.isRequired,
userCurrency: PropTypes.string.isRequired,
updateProducts: PropTypes.func.isRequired
}
export default EditForm
App.js
import React, { Component } from 'react'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
import ProductList from './ProductList'
import SingleProduct from './SingleProduct'
import Header from './Header'
import EditForm from './EditForm'
import Footer from './Footer'
import allProducts from '../data/products.json'
import '../scss/index.scss'
class App extends Component {
constructor() {
super()
this.state = {
selectedCurrency: 'AUD',
products: []
}
}
componentDidMount() {
this.setState({
products: this.getLocalProducts()
})
}
// Checks localStorage for existing product data.
// If none, initiates localStorage with raw products data
// and returns raw products to be added to state.
getLocalProducts() {
const localData = localStorage.getItem('allProducts')
if (localData !== 'undefined' && localData !== null) {
return JSON.parse(localData)
} else {
localStorage.setItem('allProducts', JSON.stringify(allProducts))
return allProducts
}
}
// Updates localStorage and state.
updateProducts = data => {
localStorage.setItem('allProducts', JSON.stringify(data))
this.setState({ products: data })
}
clearRedirect = () => {
this.setState({ redirect: false })
}
handleCurrencyChange(e) {
this.setState({ selectedCurrency: e.value })
}
render() {
const { selectedCurrency, products } = this.state
return (
<Router>
<div className="app">
<Header
handleChange={e => this.handleCurrencyChange(e)}
userCurrency={selectedCurrency}
/>
<Switch>
<Route
path="/products/:id/edit"
component={({ match }) => (
<EditForm
productId={parseInt(match.params.id)}
userCurrency={selectedCurrency}
allProducts={products}
updateProducts={this.updateProducts}
/>
)}
/>
<Route
path="/products/:id"
component={({ match }) => (
<SingleProduct
productId={parseInt(match.params.id)}
allProducts={this.getLocalProducts()}
userCurrency={selectedCurrency}
/>
)}
/>
<Route
path="/"
exact
component={() => (
<ProductList
allProducts={products}
userCurrency={selectedCurrency}
/>
)}
/>
</Switch>
<Footer />
</div>
</Router>
)
}
}
export default App
我认为您需要对 impl 进行一些澄清,因此请提供 fiddle 或其他信息。
与此同时,我猜您需要在提交表单时重定向?
如果是这样,
import { useHistory } from "react-router-dom";
并做
let history = useHistory();
function handleSubmit() {
props.handleSubmit() // the one that comes from your App
history.push("/home");
}
一旦您提供更多信息,我将相应地编辑答案。
改为使用 this.props.history.push('/')
重定向到您的主页
目标 - 我有一个用于更新产品详细信息的表格。 我想在提交表单时重定向到主页。
问题 是我将表单数据从我的 Form
组件发送到主 App
组件以更新产品列表。产品处于我的 App
状态,并作为道具传递给我的 Form
,这会导致 Form
组件重新渲染。
Form
有一个在构造函数中设置为 false 的状态标志:toHome: false
。我的计划是利用 react-router 的 Redirect
在标志设置为 true 时触发。
在 EditForm
handleSubmit 方法中有一个 setState({ toHome: true })
。但是在 handleSubmit 中还有方法(作为道具从 App
传递)来更新处于 App
状态的产品。
TLDR -> Form
handleSubmit 更新产品 -> Form
重新呈现 -> 重定向标志 (toHome
) 设置为 false在构造函数中 - >重定向永远不会发生。
即使我想添加一个简短的成功消息,我也有同样的问题。我已经坚持这个太久了。
EditForm.js
import React, { Component } from 'react'
import { Link, Redirect } from 'react-router-dom'
import PropTypes from 'prop-types'
class EditForm extends Component {
constructor(props) {
super(props)
this.state = {
product: {
id: '',
name: '',
description: '',
price: {
base: '',
amount: ''
},
relatedProducts: []
},
productIndex: '',
toHome: false
}
}
componentDidMount() {
const { productId, allProducts } = this.props
const thisProduct = this.findProduct(productId, allProducts)
const thisIndex = this.findIndex(productId, allProducts)
this.setState({ product: { ...thisProduct }, productIndex: thisIndex })
}
.........
handleSubmit(e) {
e.preventDefault()
const newAllProducts = this.mergeProducts()
// this is the method that's firing the re-render
this.props.updateProducts(newAllProducts)
// and here is the ill-fated setState
this.setState({ toHome: true })
}
render() {
const { id, name, description, price, toHome } = this.state.product
console.log(this.state.toHome)
if (toHome) {
return <Redirect to="/" />
}
return (
<div className="edit-form">
....form...
</div>
</div>
)
}
}
EditForm.propTypes = {
productId: PropTypes.number.isRequired,
allProducts: PropTypes.array.isRequired,
userCurrency: PropTypes.string.isRequired,
updateProducts: PropTypes.func.isRequired
}
export default EditForm
App.js
import React, { Component } from 'react'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
import ProductList from './ProductList'
import SingleProduct from './SingleProduct'
import Header from './Header'
import EditForm from './EditForm'
import Footer from './Footer'
import allProducts from '../data/products.json'
import '../scss/index.scss'
class App extends Component {
constructor() {
super()
this.state = {
selectedCurrency: 'AUD',
products: []
}
}
componentDidMount() {
this.setState({
products: this.getLocalProducts()
})
}
// Checks localStorage for existing product data.
// If none, initiates localStorage with raw products data
// and returns raw products to be added to state.
getLocalProducts() {
const localData = localStorage.getItem('allProducts')
if (localData !== 'undefined' && localData !== null) {
return JSON.parse(localData)
} else {
localStorage.setItem('allProducts', JSON.stringify(allProducts))
return allProducts
}
}
// Updates localStorage and state.
updateProducts = data => {
localStorage.setItem('allProducts', JSON.stringify(data))
this.setState({ products: data })
}
clearRedirect = () => {
this.setState({ redirect: false })
}
handleCurrencyChange(e) {
this.setState({ selectedCurrency: e.value })
}
render() {
const { selectedCurrency, products } = this.state
return (
<Router>
<div className="app">
<Header
handleChange={e => this.handleCurrencyChange(e)}
userCurrency={selectedCurrency}
/>
<Switch>
<Route
path="/products/:id/edit"
component={({ match }) => (
<EditForm
productId={parseInt(match.params.id)}
userCurrency={selectedCurrency}
allProducts={products}
updateProducts={this.updateProducts}
/>
)}
/>
<Route
path="/products/:id"
component={({ match }) => (
<SingleProduct
productId={parseInt(match.params.id)}
allProducts={this.getLocalProducts()}
userCurrency={selectedCurrency}
/>
)}
/>
<Route
path="/"
exact
component={() => (
<ProductList
allProducts={products}
userCurrency={selectedCurrency}
/>
)}
/>
</Switch>
<Footer />
</div>
</Router>
)
}
}
export default App
我认为您需要对 impl 进行一些澄清,因此请提供 fiddle 或其他信息。
与此同时,我猜您需要在提交表单时重定向?
如果是这样,
import { useHistory } from "react-router-dom";
并做
let history = useHistory();
function handleSubmit() {
props.handleSubmit() // the one that comes from your App
history.push("/home");
}
一旦您提供更多信息,我将相应地编辑答案。
改为使用 this.props.history.push('/')
重定向到您的主页