简体   繁体   English

Redux state 在操作分派后未更新

[英]Redux state not updating after action dispatched

I have a form for users to enter their details and press submit.我有一个表格供用户输入他们的详细信息并按提交。 This is supposed to dispatch an action and update the state by .concat() a class to it.这应该调度一个动作并通过.concat() a class 更新 state 到它。 Unfortunately the state isn't updating and I don't know why.不幸的是 state 没有更新,我不知道为什么。 If I take out useCallBack() or useEffect() from the code, the emulator freezes and I suspect infinite loops.如果我从代码中取出useCallBack()useEffect() ,模拟器会冻结,我怀疑是无限循环。

Redux Reducer 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 action 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
        }
    }
}

The class 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

The Component组件

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

I really don't know why it's not updating.我真的不知道为什么它不更新。

first of all, you shouldn't store classes in the redux store, the store should only exists of plain objects.首先,您不应该在 redux 存储中存储类,存储应该只存在于普通对象中。 but if you really want to store the class:但如果你真的想存储 class:

The real problem seams to be return {...state, account: state.account.concat(newAccount) } .真正的问题接缝return {...state, account: state.account.concat(newAccount) } here you concat the existing array with the new class, but that doesn't work.在这里,您将现有阵列与新的 class 连接起来,但这不起作用。

your store looks like this if you do so:如果你这样做,你的商店看起来像这样:

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

so your selector ( state.account.email ) will return undefined.所以你的选择器( state.account.email )将返回未定义。 you can use ( state.account[0].email )你可以使用( state.account[0].email

or you can fix it by fixing the real problem:或者您可以通过解决真正的问题来解决它:

return { ...state, account: newAccount }

also your initialState shouldn't be a an array for account as it will never be an array, it will be an Account class (this is why you don't get an error by what you are doing).你的 initialState 也不应该是 account 的数组,因为它永远不会是一个数组,它将是一个Account class (这就是为什么你不会因为你正在做的事情而出错)。 set it to null .将其设置为null

const initialState = {
  account: null,
}

I really don't know why this doesn't work.我真的不知道为什么这不起作用。 Just want to give you an advice to make it more simple and clearer (from my point of view):只是想给你一个建议,让它更简单、更清晰(从我的角度来看):

You can drop side effects like useEffect .您可以删除诸如useEffect类的副作用。 To achieve this just move local state to redux state and then you will be able to just dispatch the action from your navigationOptions component.要实现这一点,只需将本地 state 移动到 redux state 然后您就可以从您的navigationOptions组件中调度操作。 It could look like:它可能看起来像:

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());
  ...
}

I used redux-thunk in this example.我在这个例子中使用了redux-thunk

I believe, this approach will give you more flexible way to debug and extend your business logic.我相信,这种方法将为您提供更灵活的方式来调试和扩展您的业务逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM