Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何修复reducer以返回对象的属性值?_Reactjs_React Native_Redux_Redux Reducers - Fatal编程技术网

Reactjs 如何修复reducer以返回对象的属性值?

Reactjs 如何修复reducer以返回对象的属性值?,reactjs,react-native,redux,redux-reducers,Reactjs,React Native,Redux,Redux Reducers,我的react原生应用程序中有一个reducer,理想情况下,它应该检查状态并返回配方是否受欢迎。我已经尝试创建一个reducer来返回状态中的recipe对象的isFav是true还是false。如果未在状态中找到配方,则应返回false 我在想如何写减速机时遇到了麻烦。这就是我目前所拥有的 这是我的最爱 import { TOGGLE, IS_FAVOURITE } from '../actions' export const favids = (state = [], action) =

我的react原生应用程序中有一个reducer,理想情况下,它应该检查状态并返回配方是否受欢迎。我已经尝试创建一个reducer来返回状态中的recipe对象的isFav是true还是false。如果未在状态中找到配方,则应返回false

我在想如何写减速机时遇到了麻烦。这就是我目前所拥有的

这是我的最爱

import { TOGGLE, IS_FAVOURITE } from '../actions'

export const favids = (state = [], action) => {
    const { type, recipeid } = action

    const newRecipe = {
        recipeid,
        is_fav: true,
    }

    switch (type) {
        case TOGGLE: {
          //   console.log(`Toggle State = ${JSON.stringify(state)}`)
           //  console.log(`Toggle recipe id : ${recipeid}`)
            return state.findIndex(recipe => recipe.recipeid === recipeid) === -1 ?
                [...state, newRecipe] :
                state.map(recipe =>
                    recipe.recipeid === recipeid ?
                        { ...recipe, is_fav: !recipe.is_fav } : recipe
                )
        }
        case IS_FAVOURITE: {
            //console.log(`Is Favourite state =${JSON.stringify(state)}`)
            return state.map(recipe =>
                recipe.recipeid === recipeid ?
                    recipe.is_fav : state
            )
        }
        default:
            return state
    }
}
这是我的actions.js

export const TOGGLE = 'TOGGLE'
export const toggleFavId = id => ({
    type: 'TOGGLE',
    recipeid: id
})

export const IS_FAVOURITE = 'IS_FAVOURITE'
export const isFavourite = id => (
    {
        type: 'IS_FAVOURITE',
        recipeid: id
    }
)
我试图修改is_favorite reducer以返回true或false,这是保存在状态中的配方对象的is_fav属性的值

在渲染组件时,我尝试在可见组件的useEffect中调用此函数

这是favicon.js文件

import React, {useState, useEffect} from 'react'
import { FontAwesome } from '@expo/vector-icons'
import { View, TouchableOpacity,StyleSheet, Text, Alert } from 'react-native'

const FavIcon = ({recipeid, onToggle, isFavourite, text}) => {

  const [isFavNew, setFavNew] = useState(false)

  const toggleFav = (recipeid) =>{
    setFavNew(!isFavNew)
    onToggle(recipeid)
  }

  useEffect(() => {
    console.log("Entered useEffect")
    console.log(`Recipeid = ${recipeid}`)

    console.log(`Favicon UseEffect IS Favourtie Recipe id:> ${JSON.stringify(isFavourite(recipeid))}`)
    **// if (recipeid > 0) 
    //   setFavNew((isFavourite(recipeid))
    // else {
    //   setFavNew(false)
    // }**
  },[])
  
 // console.log(`Is Favourite in Favicon is = ${isFavourite(recipeid)}`)

   return (
        <View>
            <TouchableOpacity style={styles.favItem} onPress={() => toggleFav(recipeid)}>
                <FontAwesome name={isFavNew === true ? 'heart' : 'heart-o'} size={40} color='red' />
               <Text> {text}</Text>
            </TouchableOpacity>
        </View>
    )
}

export default FavIcon
import React,{useState,useffect}来自“React”
从“@expo/vector icons”导入{FontAwesome}
从“react native”导入{View、TouchableOpacity、样式表、文本、警报}
const FavIcon=({recipeid,onToggle,isFavorite,text})=>{
const[isFavNew,setFavNew]=useState(false)
const toggleFav=(recipeid)=>{
setFavNew(!isFavNew)
onToggle(recipeid)
}
useffect(()=>{
console.log(“输入useffect”)
log(`Recipeid=${Recipeid}`)
log(`Favicon useffect IS favorite Recipe id:>${JSON.stringify(isfavorite(recipeid))}`)
**//如果(recipeid>0)
//setFavNew((isfavorite(recipeid))
//否则{
//setFavNew(假)
// }**
},[])
//log(`Is Favicon中的收藏夹Is=${IsFavorite(recipeid)}`)
返回(
切换FAV(recipeid)}>
{text}
)
}
导出默认FavIcon

如果我正确理解您的问题,那是因为对Redux的误解。您正在寻找一个选择器,而不是由reducer处理的操作

Redux不过是一个大而奇特的对象。还原器修改对象的属性。操作告诉还原器如何做。选择器将这些属性返回给您

您可以在减速器中删除具有相同名称的切换动作和大小写。然后创建一个选择器,如下所示:

const isRecipeFavorited=(recipeId)=>(状态)=>{
const recipe=state.find(recipe=>recipe.id==recipeId;
返回配方?配方.is_fav:false;
};
选择器是一个将整个状态作为参数并返回子集的函数。当您使用
useSelector
时,Redux会为您传递整个状态。因此,像这样的函数就是“选择器工厂”,其中您将使用配方ID调用它,它将返回该配方的选择器。您将如下使用它:

从'react redux'导入{useSelector};
从{selectors path}导入{isRecipeFavorited};
...
常量RecipeFavorited=useSelector(isRecipeFavorited(recipeId));

另一方面,如果您最终获得大量状态信息,您可以进行一些优化。最重要的是将您的配方存储在一个对象中,而不是存储在一个数组中。我假设您从API获得了一个配方数组。假设您可以依靠唯一的配方ID,您可以迭代粗略绘制阵列并将每个阵列存储在一个对象中:

const recipesState = {};

returnedRecipes.forEach(recipe => {
    recipesState[recipe.id] = recipe;
};
然后,当您在还原器中选择配方时,您不必遍历整个列表以获得所需的配方或存储结果。您可以在O(1)时间内完成这些操作,因为您已经知道配方ID

然后,您的
是您最喜欢的
减速器壳,可能看起来像:

大小写切换:{
const tempRecipes={…state};
const currentRecipe=tempRecipes[recipeId];
当前配方
?currentRecipe.is_fav=!currentRecipe.is_fav
:tempRecipes[recipeId]=新配方;
返回菜谱;
}
然后,您可以像这样设计我上面描述的选择器:

const isRecipeFavorited=(recipeId)=>({recipe})=>recipe[recipeId]
?配方[recipeId]。是否为fav
:假;

非常感谢您,我一直在努力解决这个问题。我尝试更新您提到的代码,但我一直收到一个错误,说_selectors.isRecipeFavorited不是一个函数。我还尝试使用useEffect修复它,但没有修复错误。
从“../selectors/selectors”导入{isRecipeFavorited}{useSelector}来自'react redux'const FavIcon=({recipeid,onToggle,IsFavorite,text})=>{const[isFavRecipe,setIsFavRecipe]=useState(false)useEffect((recipeid)=>{SetIsFavRecipeId(useSelector(isRecipeFavorited,recipeid))},[])const isFavNew=useSelector(isRecipeFavorited(recipeid))
我制作了一个代码笔来展示我对此的建议。不要将IsFavorite属性存储在本地状态中——尽可能依赖状态的Redux。这消除了对useEffect的需要,也不需要调用挂钩(如useSelector)除了函数组件的根目录之外的任何位置。我在这里重新提交了这个问题,并提供了有关代码的更多信息。我仍然收到错误消息,即_selectors.isRecipeFavorited不是函数。