从 React 组件调用时 Thunk Fetch 未定义
Thunk Fetch is Undefined When Called from React Component
我正在玩从表单提交调用的 Thunk 函数,但不得不停止,因为提取 return 在组件内部未定义并且不会触发 .then()。
我不明白为什么,我将 Thunk 简化为它的核心,但仍然没有运气。我在同一个应用程序中与另一个表单有相同的模式,并且运行顺利。后端回答正确。
// actions/users.actions.js
export const login = (formData) => {
return (dispatch) => {
return fetch("http://localhost:3001/login", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(formData)
}).then(res => res.json())
}
}
// containers/LoginForm.js
import React, { Component } from 'react'
import { connect } from "react-redux";
import { Link } from 'react-router-dom'
import { login } from '../actions/users.actions'
class LoginForm extends Component {
state = {
username: '',
password: ''
}
handleChange = (e) => {
this.setState({
...this.state,
[e.target.name]: e.target.value
})
}
fetchOnSubmit = (e) => {
e.preventDefault()
this.props.login(this.state)
//=> at this point it says TypeError: Cannot read property 'then' of undefined
.then(res => this.props.errors ? null : this.props.history.push(`/`))
}
render() {
return (
<form onSubmit={this.fetchOnSubmit}>
{ this.props.alert.message &&
<div className={`alert ${this.props.alert.type}`}>
{this.props.alert.message.split('<b>').splice(0,1)}
<b>{this.props.alert.message.split('<b>').splice(1,1)}</b>
</div>
}
<h2 className='text-dark mb-4'>Login{' '}
{this.props.submitting &&
<img alt="spinner" src="data:image/gif;...." />
}
</h2>
<div>
<fieldset className='ml-auto mr-auto w-100'>
<label htmlFor="username" className="block">
Username*
<span className="text-red-400"></span>
</label>
<input
type="text"
name="username"
className='w-100 border border-primary shadow p-2 mb-4 rounded'
onChange={this.handleChange}>
</input>
</fieldset>
</div>
<div>
<fieldset className='ml-auto mr-auto w-100'>
<label htmlFor="password" className="block">
Password*
<span className="text-red-400"></span>
</label>
<input
type="password"
name="password"
className='w-100 border border-primary shadow p-2 mb-4 rounded-3 rounded'
onChange={this.handleChange}>
</input>
</fieldset>
</div>
<div class="row mb-5 ml-2 mr-2 mt-3">
<div class="col-8 d-flex"><button className='h-1 border-0 rounded-pill ml-auto mr-auto'
style={{width:'100%',display:'inline'}} type='Submit'>Login</button></div>
<div class="col-4 d-flex">
<Link to="/Signup" className='ml-auto mr-auto mt-auto mb-auto text-primary hardlink'>Register</Link>
</div>
</div>
</form>
)
}
}
const mapStateToProps = state => {
return {
submitting: state.sessions.submitting,
alert: state.alert,
errors: state.sessions.errors
}
}
const mapDispatchToProps = dispatch => {
return {
login: (credentials) => {
dispatch(login(credentials))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
如何避免出现错误 TypeError: Cannot read property 'then' of undefined
。
我什至尝试 return 动作创建者的承诺,但它不起作用。
问题
看起来你 mapDispatchToProps
中的匿名函数是空的 return。您声明了一个函数作用域,但没有 return 任何东西。
const mapDispatchToProps = dispatch => {
return {
login: (credentials) => {
dispatch(login(credentials))
// <-- nothing returned here
}
}
}
解决方案
Return 调度的动作
const mapDispatchToProps = dispatch => {
return {
login: (credentials) => {
return dispatch(login(credentials));
}
}
}
或使用隐式箭头函数return
const mapDispatchToProps = dispatch => {
return {
login: (credentials) => dispatch(login(credentials)),
}
}
并且由于在 mapDispatchToProps
中传递的所有动作创建者都自动包装在调度调用中,您可以将其更简洁地写为一个对象
const mapDispatchToProps = {
login,
}
我正在玩从表单提交调用的 Thunk 函数,但不得不停止,因为提取 return 在组件内部未定义并且不会触发 .then()。 我不明白为什么,我将 Thunk 简化为它的核心,但仍然没有运气。我在同一个应用程序中与另一个表单有相同的模式,并且运行顺利。后端回答正确。
// actions/users.actions.js
export const login = (formData) => {
return (dispatch) => {
return fetch("http://localhost:3001/login", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify(formData)
}).then(res => res.json())
}
}
// containers/LoginForm.js
import React, { Component } from 'react'
import { connect } from "react-redux";
import { Link } from 'react-router-dom'
import { login } from '../actions/users.actions'
class LoginForm extends Component {
state = {
username: '',
password: ''
}
handleChange = (e) => {
this.setState({
...this.state,
[e.target.name]: e.target.value
})
}
fetchOnSubmit = (e) => {
e.preventDefault()
this.props.login(this.state)
//=> at this point it says TypeError: Cannot read property 'then' of undefined
.then(res => this.props.errors ? null : this.props.history.push(`/`))
}
render() {
return (
<form onSubmit={this.fetchOnSubmit}>
{ this.props.alert.message &&
<div className={`alert ${this.props.alert.type}`}>
{this.props.alert.message.split('<b>').splice(0,1)}
<b>{this.props.alert.message.split('<b>').splice(1,1)}</b>
</div>
}
<h2 className='text-dark mb-4'>Login{' '}
{this.props.submitting &&
<img alt="spinner" src="data:image/gif;...." />
}
</h2>
<div>
<fieldset className='ml-auto mr-auto w-100'>
<label htmlFor="username" className="block">
Username*
<span className="text-red-400"></span>
</label>
<input
type="text"
name="username"
className='w-100 border border-primary shadow p-2 mb-4 rounded'
onChange={this.handleChange}>
</input>
</fieldset>
</div>
<div>
<fieldset className='ml-auto mr-auto w-100'>
<label htmlFor="password" className="block">
Password*
<span className="text-red-400"></span>
</label>
<input
type="password"
name="password"
className='w-100 border border-primary shadow p-2 mb-4 rounded-3 rounded'
onChange={this.handleChange}>
</input>
</fieldset>
</div>
<div class="row mb-5 ml-2 mr-2 mt-3">
<div class="col-8 d-flex"><button className='h-1 border-0 rounded-pill ml-auto mr-auto'
style={{width:'100%',display:'inline'}} type='Submit'>Login</button></div>
<div class="col-4 d-flex">
<Link to="/Signup" className='ml-auto mr-auto mt-auto mb-auto text-primary hardlink'>Register</Link>
</div>
</div>
</form>
)
}
}
const mapStateToProps = state => {
return {
submitting: state.sessions.submitting,
alert: state.alert,
errors: state.sessions.errors
}
}
const mapDispatchToProps = dispatch => {
return {
login: (credentials) => {
dispatch(login(credentials))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);
如何避免出现错误 TypeError: Cannot read property 'then' of undefined
。
我什至尝试 return 动作创建者的承诺,但它不起作用。
问题
看起来你 mapDispatchToProps
中的匿名函数是空的 return。您声明了一个函数作用域,但没有 return 任何东西。
const mapDispatchToProps = dispatch => {
return {
login: (credentials) => {
dispatch(login(credentials))
// <-- nothing returned here
}
}
}
解决方案
Return 调度的动作
const mapDispatchToProps = dispatch => {
return {
login: (credentials) => {
return dispatch(login(credentials));
}
}
}
或使用隐式箭头函数return
const mapDispatchToProps = dispatch => {
return {
login: (credentials) => dispatch(login(credentials)),
}
}
并且由于在 mapDispatchToProps
中传递的所有动作创建者都自动包装在调度调用中,您可以将其更简洁地写为一个对象
const mapDispatchToProps = {
login,
}