Reactjs 提交表单并更改状态后,应用程序重置为初始屏幕

Reactjs 提交表单并更改状态后,应用程序重置为初始屏幕,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

提交表单后,应用程序重置为初始屏幕(redux表单或Formik)。登录屏幕是初始路由中的第二个屏幕(第一个是开始屏幕)。在提交一个调用分派并返回新状态->{…状态,{isLoading:true}之后,在这一步中,我的应用程序被重置

我做错了什么?如何使窗体在不重置的情况下工作

LoginScreen.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/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?如果是,您可以分享您如何进行路由吗?