Как передать состояние контейнера в реагировать на родной - PullRequest
0 голосов
/ 08 сентября 2018

Я учусь реагировать на родной язык и создаю приложение. Для некоторых понятий я не могу понять, где происходит магия. Я использую избыточное хранилище для управления данными.

У меня есть компонент входа без сохранения состояния.

export class Login extends Component {
   onChangeText = (key, value) => {
     this.props.user[key] = value
  }

  render() {
    const { user, fetchUserDetails } = this.props
    return (
      <View style={styles.container}>
        <Text style={styles.heading}>Login</Text>
        <TextInput
          placeholder='Email'
          onChangeText={val => this.onChangeText('email', val)}
          value={user.email}
        />
        <TextInput
          placeholder='Password'
          onChangeText={val => this.onChangeText('password', val)}
          value={user.password}
        />
        <TouchableOpacity onPress={this.fetchUserDetails(user)}>
          <View style={styles.button}>
            <Text style={styles.buttonText}>Login</Text>
          </View>
        </TouchableOpacity>
      </View>
    )
  }
}

Это мой логин-контейнер

class LoginContainer extends Component {

  render () {
    return (
      <Login/>
    )
  }
}

const mapStateToProps = (state) => ({
  user: state.loginReducer.user,
})

const mapDispatchToProps = {
  ...fetchUserDetails,
}

export default connect(mapStateToProps, mapDispatchToProps)(Login)

мой редуктор выглядит так:

const initialState = {
  user: {
    email: '',
    password: '',
  }
}

const loginReducer = (state = initialState, action) => {
  switch(action.type) {
    case GET_USER:
      return Object.assign({}, state, {
        user: action.user
      })
    default:
      return state
  }
  return state
}

export default loginReducer

Мои действия выглядят примерно так:

export const GET_USER = 'GET_USER'
export function fetchUserDetails (user) {
  console.log("executing fetch user action")
  if (user === '')
  {
    alert('please complete form')
  }
  return {
    type: GET_USER,
    user
  }
}

Мой корневой редуктор:

import { combineReducers } from 'redux';
import loginReducer from './loginReducer'
const rootReducer = combineReducers({
  loginReducer
})

export default rootReducer

Мой магазин настройки:

import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import rootReducer from './reducers'

const persistConfig = {
  key: 'mykey',
  storage,
}

const persistedReducer = persistReducer(persistConfig, rootReducer)
const store = createStore(persistedReducer)
const persistedStore = persistStore(store)

export default store

Мне нужен компонент без сохранения состояния, который напрямую обновляет состояние пользовательских атрибутов в хранилище с избыточностью. Я не могу следить за тем, как состояние или действия будут передаваться компоненту входа. Любое объяснение будет оценено.

Ответы [ 2 ]

0 голосов
/ 08 сентября 2018

Управление избыточным хранилищем в Reaction-native в основном такое же, как и в реагировании.

Из того, что я понимаю, вы пытаетесь хранить данные о пользователях в избыточном хранилище для каждого события onChangeText и отражать обновленное состояние в компоненте Login.

Во-первых, вы должны использовать отдельную пару редукторов действий для настройки пользовательских данных в редуксе. Также вы, скорее всего, захотите вызвать какой-нибудь API при отправке формы и сохранить ответ в избыточном количестве, для этого вам может потребоваться другая пара действий и восстановителя. Я оставлю это тебе

Вот как вы можете управлять пользовательскими данными в избыточном ...

Ваш компонент входа без сохранения состояния.

export class Login extends Component {
   onChangeText = (value, key) => {
     this.props.setUserDetails({
       ...this.props.user,
       [key]: value
     })
  }

  render() {
    const { user, onSubmitForm } = this.props
    console.log('user===>', this.props);
    return (
      <View style={styles.container}>
        <Text style={styles.heading}>Login</Text>
        <TextInput
          placeholder='Email'
          onChangeText={val => this.onChangeText(val, 'email')}
          placeholderTextColor={'rgba(0,40,70,0.5)'}
          value={user.email}
        />
        <TextInput
          placeholder='Password'
          onChangeText={val => this.onChangeText(val, 'password')}
          placeholderTextColor={'rgba(0,40,70,0.5)'}
          value={user.password}
        />
        <TouchableOpacity onPress={() => onSubmitForm(user)}>
          <View style={styles.button}>
            <Text style={styles.buttonText}>Login</Text>
          </View>
        </TouchableOpacity>
      </View>
    )
  }
}

...

Ваш логин-контейнер.

class LoginContainer extends Component {
  onSubmitForm = () => {
    // Checking Validations
    const { name, email } = this.props;
    if (!name || !email) {
      alert('Please fill the form')
      return;
    }

    // call some API for verification and handle the response here
  }

  render () {
    return (
      <Login
        user={this.props.user}
        setUserDetails={this.props.setUserDetails}
        onSubmitForm={this.onSubmitForm}
      />
    )
  }
}

const mapStateToProps = (state) => ({
  user: state.userReducer.user,
})

const mapDispatchToProps = dispatch => ({
  setUserDetails: payload => dispatch(setUserDetails(payload)),
})

export default connect(mapStateToProps, mapDispatchToProps)(LoginContainer)

...

Ваш редуктор для настройки пользовательских данных

const initialState = {
  user: {
    email: '',
    password: '',
  }
}

const userReducer = (state = initialState, action) => {
  switch(action.type) {
    case 'SET_USER_DETAILS':
      return Object.assign({}, state, {
        user: action.user
      })
    default:
      return state
  }
  return state
}

export default userReducer

...

Ваш магазин останется прежним, а rootReducer должен быть

import { combineReducers } from 'redux';
import userReducer from './reducer'

const rootReducer = combineReducers({
  userReducer
})

export default rootReducer

...

Наконец-то ваше действие

export const SET_USER_DETAILS = 'SET_USER_DETAILS'

export function setUserDetails (user) {
  return {
    type: 'SET_USER_DETAILS',
    user
  }
}

...

Надеюсь, это поможет.

0 голосов
/ 08 сентября 2018

Надеюсь, что поможет:

Логин:

Вы НИКОГДА не должны обновлять реквизиты компонента внутри указанного компонента.

Из Реакции документации :

Реквизит только для чтения

Если вы хотите, чтобы ваше состояние (правда) было сохранено в компоненте входа в систему, сохраните его как правильное состояние и отправьте это локальное состояние при отправке:

onChangeText = (key, value) => {
   this.setState((state) => ({ ...state, [key] => value}))
}

Однако, если вы хотите сохранить свое состояние в избыточном коде, вам потребуется создать действие, которое может быть запущено для обновления избыточного состояния. Это действие должно быть передано в ваш компонент компонентов и называется так onChangeText={val => this.props.onChangeText('email', val)}

Кроме того, вы вызываете функцию fetchUserDetails при рендеринге, где вы должны передавать обратный вызов. this.fetchUserDetails не существует, this.props.fetchUserDetails существует. Код входа становится

<TouchableOpacity onPress={() => fetchUserDetails(user)}>

Контейнер для входа:

mapDispatchToProps должна быть функцией, которая принимает dispatch в качестве первого параметра ИЛИ объект, где каждая функция является создателем действия. Из документации Redux :

Если объект передается, предполагается, что каждая функция внутри него является создателем действий Redux. Объект с теми же именами функций, но с каждым создателем действия, включенным в диспетчерский вызов, чтобы их можно было вызывать напрямую, будет объединен в подпорки компонента.

Итак код, который вы написали:

const mapDispatchToProps = {
  ...fetchUserDetails,
}

Эквивалентно этому коду

function mapDispatchToProps(dispatch) {
    return {
        fetchUserDetails: (user) => dispatch(fetchUserDetails(user))
    },
}

Функция dispatch - это место, где происходит волшебство, каждое отправленное действие передается вашим редукторам, где вы можете создать новое состояние на основе действия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...