Reactjs 提交表单并更改状态后,应用程序重置为初始屏幕
提交表单后,应用程序重置为初始屏幕(redux表单或Formik)。登录屏幕是初始路由中的第二个屏幕(第一个是开始屏幕)。在提交一个调用分派并返回新状态->{…状态,{isLoading:true}之后,在这一步中,我的应用程序被重置 我做错了什么?如何使窗体在不重置的情况下工作 LoginScreen.jsReactjs 提交表单并更改状态后,应用程序重置为初始屏幕,reactjs,react-native,redux,react-navigation,redux-form,Reactjs,React Native,Redux,React Navigation,Redux Form,提交表单后,应用程序重置为初始屏幕(redux表单或Formik)。登录屏幕是初始路由中的第二个屏幕(第一个是开始屏幕)。在提交一个调用分派并返回新状态->{…状态,{isLoading:true}之后,在这一步中,我的应用程序被重置 我做错了什么?如何使窗体在不重置的情况下工作 LoginScreen.js import React, { Component } from 'react' import { View, Text, Button } from 'react-native' imp
import React, { Component } from 'react'
import { View, Text, Button } from 'react-native'
import { connect } from 'react-redux'
import { LoginForm } from '../../forms'
import { userLogin } from '../../store/modules/account'
import s from './styles'
class LoginScreen extends Component {
onLogin = (values, bag) => {
const { userLogin } = this.props
const { email, password } = values
userLogin({ email, password })
}
render() {
const { account, navigation } = this.props
return (
<View style={s.wrapper}>
<View style={s.mainContainer}>
<Text>This is SignIiiiiiin!</Text>
<LoginForm
handleLogin={this.onLogin}
/>
</View>
</View>
)
}
}
const mapStateToProps = ({ account }) => ({
account,
})
export default connect(mapStateToProps, {
userLogin
})(LoginScreen)
import React, { Component } from 'react'
import { View, TouchableOpacity, Button } from 'react-native'
import { Formik } from 'formik'
import { FieldInput } from '../../components'
import s from './styles'
class LoginForm extends Component {
render() {
const {
handleLogin,
} = this.props
return (
<View style={s.wrapper}>
<Formik
initialValues={{ email: '', password: '', confirmPassword: '' }}
onSubmit={handleLogin}
render={({
values,
handleSubmit,
setFieldValue,
errors,
touched,
setFieldTouched,
isValid,
isSubmitting,
}) => (
<React.Fragment>
<FieldInput
label="Email"
autoCapitalize="none"
value={values.email}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="email"
error={touched.email && errors.email}
/>
<FieldInput
label="Password"
autoCapitalize="none"
secureTextEntry
value={values.password}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="password"
error={touched.password && errors.password}
/>
<FieldInput
label="Confirm Password"
autoCapitalize="none"
secureTextEntry
value={values.confirmPassword}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="confirmPassword"
error={touched.confirmPassword && errors.confirmPassword}
/>
<Button
backgroundColor="blue"
title="Submit"
onPress={handleSubmit}
disabled={!isValid || isSubmitting}
loading={isSubmitting}
/>
</React.Fragment>
)}
/>
</View>
)
}
}
export default LoginForm
import { applyMiddleware, compose, createStore } from 'redux'
import thunk from 'redux-thunk'
import { persistStore, persistReducer } from 'redux-persist'
import logger from 'redux-logger'
import storage from 'redux-persist/lib/storage'
import makeRootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
blacklist: ['account']
}
const persistedReducer = persistReducer(persistConfig, makeRootReducer)
const enhancer = compose(applyMiddleware(thunk, logger))
export default function configureStore() {
const store = createStore(persistedReducer, enhancer)
const persistor = persistStore(store)
return { store, persistor }
}
import { AsyncStorage } from 'react-native'
import { cloneDeep, assignIn, merge } from 'lodash'
import axios from 'axios'
import moment from 'moment'
import CNST from '../constants'
import { ENV } from '../../config'
// ------------------------------------
// Actions
// ------------------------------------
export function userLogin(data = {}) {
const username = data.email
const password = data.password
return (dispatch) => {
dispatch({
type: CNST.ACCOUNT.LOGIN.LOADING
})
/*
axios.post(`${ENV.ROOT_URL}/user/login`, { username, password })
.then((response) => {
const { token } = response.data
const validFrom = moment().format()
dispatch({
type: CNST.ACCOUNT.LOGIN.SUCCESS,
response: { token, username, validFrom }
})
return response
})
.catch((error) => {
console.log('error', error.response)
dispatch({
type: CNST.ACCOUNT.LOGIN.FAILED,
response: error
})
})
*/
}
}
// ------------------------------------
// Reducers
// ------------------------------------
const initialState = {
id: '',
email: '',
username: '',
token: '',
error: {},
isLoading: false
}
export default function accountReducer(state = cloneDeep(initialState), action) {
switch (action.type) {
case CNST.ACCOUNT.LOGIN.SUCCESS: {
// console.log('action', action)
const { token, username, validFrom } = action.response
const _items = [
['token', token || ''],
['username', username || ''],
['validFrom', validFrom || ''],
]
AsyncStorage.multiSet(_items)
return { ...state, ...{ error: {}, token, username, email: username, isLoading: false } }
}
case CNST.ACCOUNT.LOGIN.FAILED:
return { ...state, ...{ error: action.response, isLoading: false } }
case CNST.ACCOUNT.LOGIN.LOADING:
return { ...state, ...{ isLoading: true } }
default:
return state
}
}
export default {
LOGIN: {
LOADING: 'LOGIN',
SUCCESS: 'LOGIN_SUCCESS',
FAILED: 'LOGIN_FAILED'
}
}
import { combineReducers } from 'redux'
import account from './modules/account'
export default combineReducers({
account,
})
store/modules/account.js
import React, { Component } from 'react'
import { View, Text, Button } from 'react-native'
import { connect } from 'react-redux'
import { LoginForm } from '../../forms'
import { userLogin } from '../../store/modules/account'
import s from './styles'
class LoginScreen extends Component {
onLogin = (values, bag) => {
const { userLogin } = this.props
const { email, password } = values
userLogin({ email, password })
}
render() {
const { account, navigation } = this.props
return (
<View style={s.wrapper}>
<View style={s.mainContainer}>
<Text>This is SignIiiiiiin!</Text>
<LoginForm
handleLogin={this.onLogin}
/>
</View>
</View>
)
}
}
const mapStateToProps = ({ account }) => ({
account,
})
export default connect(mapStateToProps, {
userLogin
})(LoginScreen)
import React, { Component } from 'react'
import { View, TouchableOpacity, Button } from 'react-native'
import { Formik } from 'formik'
import { FieldInput } from '../../components'
import s from './styles'
class LoginForm extends Component {
render() {
const {
handleLogin,
} = this.props
return (
<View style={s.wrapper}>
<Formik
initialValues={{ email: '', password: '', confirmPassword: '' }}
onSubmit={handleLogin}
render={({
values,
handleSubmit,
setFieldValue,
errors,
touched,
setFieldTouched,
isValid,
isSubmitting,
}) => (
<React.Fragment>
<FieldInput
label="Email"
autoCapitalize="none"
value={values.email}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="email"
error={touched.email && errors.email}
/>
<FieldInput
label="Password"
autoCapitalize="none"
secureTextEntry
value={values.password}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="password"
error={touched.password && errors.password}
/>
<FieldInput
label="Confirm Password"
autoCapitalize="none"
secureTextEntry
value={values.confirmPassword}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="confirmPassword"
error={touched.confirmPassword && errors.confirmPassword}
/>
<Button
backgroundColor="blue"
title="Submit"
onPress={handleSubmit}
disabled={!isValid || isSubmitting}
loading={isSubmitting}
/>
</React.Fragment>
)}
/>
</View>
)
}
}
export default LoginForm
import { applyMiddleware, compose, createStore } from 'redux'
import thunk from 'redux-thunk'
import { persistStore, persistReducer } from 'redux-persist'
import logger from 'redux-logger'
import storage from 'redux-persist/lib/storage'
import makeRootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
blacklist: ['account']
}
const persistedReducer = persistReducer(persistConfig, makeRootReducer)
const enhancer = compose(applyMiddleware(thunk, logger))
export default function configureStore() {
const store = createStore(persistedReducer, enhancer)
const persistor = persistStore(store)
return { store, persistor }
}
import { AsyncStorage } from 'react-native'
import { cloneDeep, assignIn, merge } from 'lodash'
import axios from 'axios'
import moment from 'moment'
import CNST from '../constants'
import { ENV } from '../../config'
// ------------------------------------
// Actions
// ------------------------------------
export function userLogin(data = {}) {
const username = data.email
const password = data.password
return (dispatch) => {
dispatch({
type: CNST.ACCOUNT.LOGIN.LOADING
})
/*
axios.post(`${ENV.ROOT_URL}/user/login`, { username, password })
.then((response) => {
const { token } = response.data
const validFrom = moment().format()
dispatch({
type: CNST.ACCOUNT.LOGIN.SUCCESS,
response: { token, username, validFrom }
})
return response
})
.catch((error) => {
console.log('error', error.response)
dispatch({
type: CNST.ACCOUNT.LOGIN.FAILED,
response: error
})
})
*/
}
}
// ------------------------------------
// Reducers
// ------------------------------------
const initialState = {
id: '',
email: '',
username: '',
token: '',
error: {},
isLoading: false
}
export default function accountReducer(state = cloneDeep(initialState), action) {
switch (action.type) {
case CNST.ACCOUNT.LOGIN.SUCCESS: {
// console.log('action', action)
const { token, username, validFrom } = action.response
const _items = [
['token', token || ''],
['username', username || ''],
['validFrom', validFrom || ''],
]
AsyncStorage.multiSet(_items)
return { ...state, ...{ error: {}, token, username, email: username, isLoading: false } }
}
case CNST.ACCOUNT.LOGIN.FAILED:
return { ...state, ...{ error: action.response, isLoading: false } }
case CNST.ACCOUNT.LOGIN.LOADING:
return { ...state, ...{ isLoading: true } }
default:
return state
}
}
export default {
LOGIN: {
LOADING: 'LOGIN',
SUCCESS: 'LOGIN_SUCCESS',
FAILED: 'LOGIN_FAILED'
}
}
import { combineReducers } from 'redux'
import account from './modules/account'
export default combineReducers({
account,
})
store/constants/account.js
import React, { Component } from 'react'
import { View, Text, Button } from 'react-native'
import { connect } from 'react-redux'
import { LoginForm } from '../../forms'
import { userLogin } from '../../store/modules/account'
import s from './styles'
class LoginScreen extends Component {
onLogin = (values, bag) => {
const { userLogin } = this.props
const { email, password } = values
userLogin({ email, password })
}
render() {
const { account, navigation } = this.props
return (
<View style={s.wrapper}>
<View style={s.mainContainer}>
<Text>This is SignIiiiiiin!</Text>
<LoginForm
handleLogin={this.onLogin}
/>
</View>
</View>
)
}
}
const mapStateToProps = ({ account }) => ({
account,
})
export default connect(mapStateToProps, {
userLogin
})(LoginScreen)
import React, { Component } from 'react'
import { View, TouchableOpacity, Button } from 'react-native'
import { Formik } from 'formik'
import { FieldInput } from '../../components'
import s from './styles'
class LoginForm extends Component {
render() {
const {
handleLogin,
} = this.props
return (
<View style={s.wrapper}>
<Formik
initialValues={{ email: '', password: '', confirmPassword: '' }}
onSubmit={handleLogin}
render={({
values,
handleSubmit,
setFieldValue,
errors,
touched,
setFieldTouched,
isValid,
isSubmitting,
}) => (
<React.Fragment>
<FieldInput
label="Email"
autoCapitalize="none"
value={values.email}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="email"
error={touched.email && errors.email}
/>
<FieldInput
label="Password"
autoCapitalize="none"
secureTextEntry
value={values.password}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="password"
error={touched.password && errors.password}
/>
<FieldInput
label="Confirm Password"
autoCapitalize="none"
secureTextEntry
value={values.confirmPassword}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="confirmPassword"
error={touched.confirmPassword && errors.confirmPassword}
/>
<Button
backgroundColor="blue"
title="Submit"
onPress={handleSubmit}
disabled={!isValid || isSubmitting}
loading={isSubmitting}
/>
</React.Fragment>
)}
/>
</View>
)
}
}
export default LoginForm
import { applyMiddleware, compose, createStore } from 'redux'
import thunk from 'redux-thunk'
import { persistStore, persistReducer } from 'redux-persist'
import logger from 'redux-logger'
import storage from 'redux-persist/lib/storage'
import makeRootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
blacklist: ['account']
}
const persistedReducer = persistReducer(persistConfig, makeRootReducer)
const enhancer = compose(applyMiddleware(thunk, logger))
export default function configureStore() {
const store = createStore(persistedReducer, enhancer)
const persistor = persistStore(store)
return { store, persistor }
}
import { AsyncStorage } from 'react-native'
import { cloneDeep, assignIn, merge } from 'lodash'
import axios from 'axios'
import moment from 'moment'
import CNST from '../constants'
import { ENV } from '../../config'
// ------------------------------------
// Actions
// ------------------------------------
export function userLogin(data = {}) {
const username = data.email
const password = data.password
return (dispatch) => {
dispatch({
type: CNST.ACCOUNT.LOGIN.LOADING
})
/*
axios.post(`${ENV.ROOT_URL}/user/login`, { username, password })
.then((response) => {
const { token } = response.data
const validFrom = moment().format()
dispatch({
type: CNST.ACCOUNT.LOGIN.SUCCESS,
response: { token, username, validFrom }
})
return response
})
.catch((error) => {
console.log('error', error.response)
dispatch({
type: CNST.ACCOUNT.LOGIN.FAILED,
response: error
})
})
*/
}
}
// ------------------------------------
// Reducers
// ------------------------------------
const initialState = {
id: '',
email: '',
username: '',
token: '',
error: {},
isLoading: false
}
export default function accountReducer(state = cloneDeep(initialState), action) {
switch (action.type) {
case CNST.ACCOUNT.LOGIN.SUCCESS: {
// console.log('action', action)
const { token, username, validFrom } = action.response
const _items = [
['token', token || ''],
['username', username || ''],
['validFrom', validFrom || ''],
]
AsyncStorage.multiSet(_items)
return { ...state, ...{ error: {}, token, username, email: username, isLoading: false } }
}
case CNST.ACCOUNT.LOGIN.FAILED:
return { ...state, ...{ error: action.response, isLoading: false } }
case CNST.ACCOUNT.LOGIN.LOADING:
return { ...state, ...{ isLoading: true } }
default:
return state
}
}
export default {
LOGIN: {
LOADING: 'LOGIN',
SUCCESS: 'LOGIN_SUCCESS',
FAILED: 'LOGIN_FAILED'
}
}
import { combineReducers } from 'redux'
import account from './modules/account'
export default combineReducers({
account,
})
store/reducers.js
import React, { Component } from 'react'
import { View, Text, Button } from 'react-native'
import { connect } from 'react-redux'
import { LoginForm } from '../../forms'
import { userLogin } from '../../store/modules/account'
import s from './styles'
class LoginScreen extends Component {
onLogin = (values, bag) => {
const { userLogin } = this.props
const { email, password } = values
userLogin({ email, password })
}
render() {
const { account, navigation } = this.props
return (
<View style={s.wrapper}>
<View style={s.mainContainer}>
<Text>This is SignIiiiiiin!</Text>
<LoginForm
handleLogin={this.onLogin}
/>
</View>
</View>
)
}
}
const mapStateToProps = ({ account }) => ({
account,
})
export default connect(mapStateToProps, {
userLogin
})(LoginScreen)
import React, { Component } from 'react'
import { View, TouchableOpacity, Button } from 'react-native'
import { Formik } from 'formik'
import { FieldInput } from '../../components'
import s from './styles'
class LoginForm extends Component {
render() {
const {
handleLogin,
} = this.props
return (
<View style={s.wrapper}>
<Formik
initialValues={{ email: '', password: '', confirmPassword: '' }}
onSubmit={handleLogin}
render={({
values,
handleSubmit,
setFieldValue,
errors,
touched,
setFieldTouched,
isValid,
isSubmitting,
}) => (
<React.Fragment>
<FieldInput
label="Email"
autoCapitalize="none"
value={values.email}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="email"
error={touched.email && errors.email}
/>
<FieldInput
label="Password"
autoCapitalize="none"
secureTextEntry
value={values.password}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="password"
error={touched.password && errors.password}
/>
<FieldInput
label="Confirm Password"
autoCapitalize="none"
secureTextEntry
value={values.confirmPassword}
onChange={setFieldValue}
onTouch={setFieldTouched}
name="confirmPassword"
error={touched.confirmPassword && errors.confirmPassword}
/>
<Button
backgroundColor="blue"
title="Submit"
onPress={handleSubmit}
disabled={!isValid || isSubmitting}
loading={isSubmitting}
/>
</React.Fragment>
)}
/>
</View>
)
}
}
export default LoginForm
import { applyMiddleware, compose, createStore } from 'redux'
import thunk from 'redux-thunk'
import { persistStore, persistReducer } from 'redux-persist'
import logger from 'redux-logger'
import storage from 'redux-persist/lib/storage'
import makeRootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
blacklist: ['account']
}
const persistedReducer = persistReducer(persistConfig, makeRootReducer)
const enhancer = compose(applyMiddleware(thunk, logger))
export default function configureStore() {
const store = createStore(persistedReducer, enhancer)
const persistor = persistStore(store)
return { store, persistor }
}
import { AsyncStorage } from 'react-native'
import { cloneDeep, assignIn, merge } from 'lodash'
import axios from 'axios'
import moment from 'moment'
import CNST from '../constants'
import { ENV } from '../../config'
// ------------------------------------
// Actions
// ------------------------------------
export function userLogin(data = {}) {
const username = data.email
const password = data.password
return (dispatch) => {
dispatch({
type: CNST.ACCOUNT.LOGIN.LOADING
})
/*
axios.post(`${ENV.ROOT_URL}/user/login`, { username, password })
.then((response) => {
const { token } = response.data
const validFrom = moment().format()
dispatch({
type: CNST.ACCOUNT.LOGIN.SUCCESS,
response: { token, username, validFrom }
})
return response
})
.catch((error) => {
console.log('error', error.response)
dispatch({
type: CNST.ACCOUNT.LOGIN.FAILED,
response: error
})
})
*/
}
}
// ------------------------------------
// Reducers
// ------------------------------------
const initialState = {
id: '',
email: '',
username: '',
token: '',
error: {},
isLoading: false
}
export default function accountReducer(state = cloneDeep(initialState), action) {
switch (action.type) {
case CNST.ACCOUNT.LOGIN.SUCCESS: {
// console.log('action', action)
const { token, username, validFrom } = action.response
const _items = [
['token', token || ''],
['username', username || ''],
['validFrom', validFrom || ''],
]
AsyncStorage.multiSet(_items)
return { ...state, ...{ error: {}, token, username, email: username, isLoading: false } }
}
case CNST.ACCOUNT.LOGIN.FAILED:
return { ...state, ...{ error: action.response, isLoading: false } }
case CNST.ACCOUNT.LOGIN.LOADING:
return { ...state, ...{ isLoading: true } }
default:
return state
}
}
export default {
LOGIN: {
LOADING: 'LOGIN',
SUCCESS: 'LOGIN_SUCCESS',
FAILED: 'LOGIN_FAILED'
}
}
import { combineReducers } from 'redux'
import account from './modules/account'
export default combineReducers({
account,
})
我解决了这个问题。问题出现在主容器中,在主容器中我安装了导航器,并通过状态来更改不同堆栈之间的路由。我传递了所有状态对象,当对象的一个项被更改时,导航器将重置导航状态
. . .
return (
<View style={{ flex: 1 }}>
<Navigator
onNavigationStateChange={() => Keyboard.dismiss()}
/>
</View>
)
}
}
const mapStateToProps = ({ account }) => ({
account // <-- bad idea
token: account.token // <-- good one
})
export default connect(mapStateToProps, {
getSomeData
})(MainContainer)
。
返回(
Keyboard.dismise()}
/>
)
}
}
常量mapStateToProps=({account})=>({
帐户//重置您的意思是路由器将您带回屏幕1,而不是让您停留在屏幕2?如果是,您可以分享您如何进行路由吗?