我有一个表格供用户输入其详细信息,然后按提交。这应该调度一个动作并通过.concat()
类向其更新状态。不幸的是状态没有更新,我也不知道为什么。如果我从代码中取出useCallBack()
或useEffect()
,则模拟器会冻结,并且我怀疑是无限循环。
Redux Reducer
// Initialised class
import newAccount from '../../models/newAccount'
import { CREATE_ACCOUNT } from '../actions/meals'
const initialState = {
account: [],
}
const addPerson = (state=initialState, action) =>{
switch(action.type){
case CREATE_ACCOUNT:
const newAccount = new newAccount(
Date.now().toString(),
action.accountData.name,
action.accountData.image,
action.accountData.email,
action.accountData.password
)
return { ...state, account: state.account.concat(newAccount) }
default:
return state
}
}
export default addPerson
Redux动作
export const CREATE_ACCOUNT = 'CREATE_ACCOUNT'
export const newAccount = (Id,name,image, email, password) => {
return {type: CREATE_ACCOUNT, accountData:{
Id: Date.now().toString(),
name: name,
image: image,
email: email,
password: password
}
}
}
班级
class newAccount {
constructor(
id,
name,
image,
email,
password
){
this.id = id;
this.name = name;
this.image = image;
this.email = email;
this.password = password;
}
}
export default newAccount
组件
import React, { useState, useCallback, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import {newAccount} from '../Store/actions/accounts'
import ImagePicker from '../Components/ImagePicker'
const AddScreen = (props) => {
const dispatch = useDispatch()
const [name, setName] = useState('')
const [selectedImage, setSelectedImage] = useState('')
const email = useSelector(state => state.account.email)
const password = useSelector(state => state.account.password)
const handleSubmit = useCallback(() => {
dispatch(newAccount(Date.now(),name,selectedImage,email,password))
},[dispatch, name, selectedImage, email, password])
useEffect(() => { handleSubmit
props.navigation.setParams({handleSubmit: handleSubmit})
},[handleSubmit])
return (
<View style={styles.container}>
<View style={styles.card}>
<ImagePicker onImageSelected={selectedImage} />
<AddForm email={email} password={password}/>
<TextInput
onChangeText={name => setName(name)}
value={name}
/>
</View>
</View>
)
}
export default AddScreen
AddScreen.navigationOptions = (navigationData) => {
const submit = navigationData.navigation.getParam('handleSubmit')
return {
headerTitle: 'Create Account',
headerRight: () => (
<TouchableOpacity onPress={submit}>
<Text style={styles.createOrange}>Create</Text>
</TouchableOpacity>
)
}
}
我真的不知道为什么它没有更新。
答案 0 :(得分:0)
首先,您不应将类存储在redux存储中,该存储应仅存在普通对象。但是如果您真的想存储该类:
实际问题似乎为return { ...state, account: state.account.concat(newAccount) }
。在这里,您将现有数组与新类连接在一起,但这不起作用。
如果您这样做,您的商店将如下所示:
{
account: [{
email: "..."
id: "..."
image: "..."
name: "..."
password: "...
}],
}
因此您的选择器(state.account.email
)将返回未定义。您可以使用(state.account[0].email
)
或者您可以通过解决实际问题来解决它:
return { ...state, account: newAccount }
您的initialState也不应该是帐户数组,因为它永远不会是数组,而是Account
类(这就是为什么在执行操作时不会出错的原因) 。将其设置为null
。
const initialState = {
account: null,
}
答案 1 :(得分:0)
我真的不知道为什么这行不通。只是想给您一个建议,使其更简单明了(从我的角度来看):
您可以删除诸如useEffect
之类的副作用。为此,只需将本地状态转换为redux状态,然后就可以从navigationOptions
组件中分派操作。它可能看起来像:
const AddScreen = () => {
const name = useSelector(...);
...
const password = useSelector(...);
// trigger action on something changes, for instance like that:
const onChange = (key, value) = dispatch(newAccountChange({[key]: value}))
// return tree of components
}
export const submitNewAccount = () => {
return (dispatch, getState) => {
const { id, name, ... } = getState().account;
dispatch(newAccount(id, name, ...));
};
}
AddScreen.navigationOptions = (navigationData) => {
const dispatch = useDispatch();
const submit = dispatch(submitNewAccount());
...
}
在此示例中,我使用了redux-thunk
。
我相信,这种方法将为您提供更灵活的调试和扩展业务逻辑的方法。