Я изучаю React Native и создаю приложение. Для некоторых концепций я не могу понять, где происходит волшебство. Я использую redux store для управления данными.
У меня есть компонент входа в систему без сохранения состояния.
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.info("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Мне нужен компонент без сохранения состояния, который напрямую обновляет состояние пользовательских атрибутов в хранилище redux. Я не могу следить за тем, как состояние или действия будут переданы компоненту входа в систему. Любое объяснение будет оценено.





Надеюсь, это поможет:
Авторизоваться:
НИКОГДА не обновляйте свойства компонента внутри указанного компонента.
Props are Read-Only
Если вы хотите, чтобы ваше состояние (истина) сохранялось в компоненте входа в систему, сохраните его как правильное состояние и отправьте это локальное состояние при отправке:
onChangeText = (key, value) => {
this.setState((state) => ({ ...state, [key] => value}))
}
Однако, если вы хотите сохранить свое состояние в redux, вам нужно будет создать действие, которое может быть запущено для обновления состояния redux. Это действие необходимо передать в свойства компонента и называть его следующим образом: onChangeText = {val => this.props.onChangeText('email', val)}.
Кроме того, вы вызываете функцию fetchUserDetails при рендеринге, где вы должны передавать обратный вызов. this.fetchUserDetails не существует, this.props.fetchUserDetails существует. Код входа становится
<TouchableOpacity onPress = {() => fetchUserDetails(user)}>
Контейнер входа в систему:
mapDispatchToProps должен быть функцией, которая принимает dispatch в качестве первого параметра ИЛИ объектом, где каждая функция является создателем действия. Из Документация Redux:
If an object is passed, each function inside it is assumed to be a Redux action creator. An object with the same function names, but with every action creator wrapped into a dispatch call so they may be invoked directly, will be merged into the component’s props.
Итак, код, который вы написали:
const mapDispatchToProps = {
...fetchUserDetails,
}
Эквивалентно этому коду
function mapDispatchToProps(dispatch) {
return {
fetchUserDetails: (user) => dispatch(fetchUserDetails(user))
},
}
Функция dispatch - это то место, где происходит волшебство, каждое отправленное действие передается вашим редукторам, где вы можете создать новое состояние на основе действия.
Управление хранилищем redux в react-native в основном такое же, как и в react.
Насколько я понимаю, вы пытаетесь хранить данные пользователя в хранилище redux для каждого события onChangeText и отражать обновленное состояние в компоненте входа в систему.
Во-первых, вы должны использовать отдельную пару редукторов действий для настройки данных пользователя в redux. Также вы, скорее всего, захотите вызвать какой-либо API при отправке формы и сохранить ответ в redux. Для этого вам может потребоваться другая пара действий и редуктора. Я оставлю это тебе
Вот как вы можете управлять данными пользователя в сокращении ...
Ваш компонент входа в систему без сохранения состояния.
export class Login extends Component {
onChangeText = (value, key) => {
this.props.setUserDetails({
...this.props.user,
[key]: value
})
}
render() {
const { user, onSubmitForm } = this.props
console.info('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
}
}
...
Надеюсь, это поможет.
Правильно ли вы настроили root-reducer. Я предполагаю, что вы назначили там состояние с именем userReducer для своего userReducer. Попробуйте проверить значения в Логин. Также проверьте, получаете ли вы правильные значения в действии и редукторе. Если нет, то правильно настройте root-reducer. Получите помощь от этого документы.
Что вы имеете в виду под «состоянием с именем userReducer»? Код, который вы разместили в своем ответе, состоит из моего пользователя Reducer.
Redux предоставляет вам функцию с именем «combReducer», которая объединяет все ваши редукторы в один редуктор, который затем передается в ваше хранилище redux. он принимает состояния отображения объектов с соответствующими редукторами. Я предполагал, что вы назвали свое состояние таким же, как имя редуктора, то есть userReducer, как этот combReducers ({userReducer: userReducer}), а затем передали его в магазин.
Да, это уже сделано, но опять же, я просто не могу получить к нему доступ. Я внесу правку, добавив свой корневой файл-редуктор и файл configureStore.
Попробуйте сейчас Я изменил несколько битов в своем ответе.
Я попробовал ваше решение, но потом у меня возникла ошибка, что user.email не определен в компоненте входа в систему. Фактически ни одно из свойств не передается компоненту входа в систему.