我正在学习本机响应,并且正在构建应用程序。对于某些概念,我无法理解魔术发生的位置。我正在使用redux存储管理数据。
我有一个无状态登录组件。
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
我需要有一个无状态组件,该组件可以直接更新redux存储中用户属性的状态。我无法了解如何将状态或操作传递给登录组件。任何解释将不胜感激。
答案 0 :(得分:3)
在react-native中管理redux存储基本上与在react中相同。
据我了解,您正在尝试在每个onChangeText事件上将用户详细信息存储在redux存储中,并在Login组件中反映更新后的状态。
首先,您应该使用单独的动作减少器对在redux中设置用户详细信息。另外,您很可能希望在表单提交时调用一些API并将响应存储在redux中。为此,您可能需要另一对操作和reducer。我留给你
这是您如何在Redux中管理用户详细信息...
您的无状态登录组件。
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)
...
您的Reducer用于设置用户详细信息
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
}
}
...
希望有帮助。
答案 1 :(得分:1)
希望有帮助:
登录:
您绝不能更新该组件内的组件props。
道具是只读的
如果您希望将状态(真相)存储在登录组件中,则将其存储为适当的状态,并在提交时发送此本地状态:
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 documentation:
如果传递了一个对象,则假定其中的每个函数都是Redux操作创建者。一个具有相同功能名称的对象,但是每个动作创建者都被包装到一个调度调用中,以便可以直接调用它们,这些对象将被合并到组件的props中。
所以您编写的代码:
const mapDispatchToProps = {
...fetchUserDetails,
}
等效于此代码
function mapDispatchToProps(dispatch) {
return {
fetchUserDetails: (user) => dispatch(fetchUserDetails(user))
},
}
神奇的地方是dispatch
函数,调度的每个动作都传递给减速器,您可以在其中根据动作创建新状态。