调度动作后,Redux状态未更新

时间:2020-07-20 11:29:15

标签: javascript react-native redux react-redux

我有一个表格供用户输入其详细信息,然后按提交。这应该调度一个动作并通过.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>
        )
    }
}

我真的不知道为什么它没有更新。

2 个答案:

答案 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

我相信,这种方法将为您提供更灵活的调试和扩展业务逻辑的方法。