簡體   English   中英

Redux state 在操作分派后未更新

[英]Redux state not updating after action dispatched

我有一個表格供用戶輸入他們的詳細信息並按提交。 這應該調度一個動作並通過.concat() a class 更新 state 到它。 不幸的是 state 沒有更新,我不知道為什么。 如果我從代碼中取出useCallBack()useEffect() ,模擬器會凍結,我懷疑是無限循環。

Redux減速機

// 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

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>
        )
    }
}

我真的不知道為什么它不更新。

首先,您不應該在 redux 存儲中存儲類,存儲應該只存在於普通對象中。 但如果你真的想存儲 class:

真正的問題接縫return {...state, account: state.account.concat(newAccount) } 在這里,您將現有陣列與新的 class 連接起來,但這不起作用。

如果你這樣做,你的商店看起來像這樣:

{
  account: [{
    email: "..."
    id: "..."
    image: "..."
    name: "..."
    password: "...
  }],
}

所以你的選擇器( state.account.email )將返回未定義。 你可以使用( state.account[0].email

或者您可以通過解決真正的問題來解決它:

return { ...state, account: newAccount }

你的 initialState 也不應該是 account 的數組,因為它永遠不會是一個數組,它將是一個Account class (這就是為什么你不會因為你正在做的事情而出錯)。 將其設置為null

const initialState = {
  account: null,
}

我真的不知道為什么這不起作用。 只是想給你一個建議,讓它更簡單、更清晰(從我的角度來看):

您可以刪除諸如useEffect類的副作用。 要實現這一點,只需將本地 state 移動到 redux state 然后您就可以從您的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

我相信,這種方法將為您提供更靈活的方式來調試和擴展您的業務邏輯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM